Blog

About Gatekeeper

Posted on: 2012-02-21 22:44:36

Great article about application security on the upcoming Mountain Lion:

About Gatekeeper: \"

Today’s Mountain Lion announcement introduces an important new security feature, called Gatekeeper, in addition to the “sandboxing” feature that premiered in Lion. I’d like to talk a little bit about it, and why it’s important to all Mac users.

Malware is out of control. Almost every day I read a new article about a major security breach in a well-known organization. There is big money to be made from stolen credit card numbers and identities. End-user applications on individual computers are a prime attack vector because, even with the best tools and the best programmers, vulnerabilities sneak their way in. Trying to make applications free of vulnerabilities (while still an important goal) is to lose the overall cat-and-mouse race.

As Mac users, we’ve mostly enjoyed a life free of the worry that has followed Windows users for years. Mac OS X is pretty damn secure. But it could be more secure. As Macs enjoy increased popularity, they become a more attractive target to identity thieves and other criminals. Sooner or later, bad people ruin every nice thing. It’s an immutable law of humanity.

So, what to do about this? Code-signing, although it can’t single-handedly fix the problem forever, is a vital weapon in the fight against malware. But many folks are unclear on how it works, or how it helps. Let me try to explain in as close to plain English as I can.

An explanation of code-signing for humans

What is code-signing? Let’s start with a slightly higher-level question: what is signing? Signing is based on technology similar to encryption, so let’s discuss them both broadly.

One of the most prevalent and secure methods of encrypting or signing data is to use what’s called a “key-pair”. As the word “pair” suggests, this means there are two keys which can “unlock” the encrypted data in certain ways.

A “key” is literally just a number. But it’s a very big number, and this is important. If I asked you to guess a number between 1 and 100, you’d have a 1% chance of guessing it on your first try, and you’d be guaranteed to guess it correctly if I gave you 100 tries. But what if I asked you to guess a number between 1 and 3 trillion? That’s a bit more of a challenge.

You’ve probably heard at least in passing about encryption keys and that they have different sizes or lengths (such as 40-bit, 128-bit, or 256-bit). Just like in my number guessing example above, longer keys are harder to guess. Each additional bit that is added to a key makes it exponentially harder to guess or figure out by brute-force attempting to decrypt the data with every possible numerical key. (Is 1 the key? No. Is 2 the key? No. Is 3 the key? Is 3,426,989,662 the key? No.)

We want encryption keys to be very long so that brute-force guessing attempts would take literally thousands of years. They become an unreasonable attack vector given the current average human lifespan.

So, why two keys? In key-pair encryption, one key is called the “private key” and the other is called the “public key”.

The keeper of the private key is able to “sign” data; a process which both identifies its origin and provides reasonable proof that it has not been altered. Private keys must be guarded very carefully, so that signatures cannot be forged.

The public key, as its name suggests, may be distributed freely. In encryption, the public key can be used to encrypt data which can only be read by the owner of the corresponding private key. In other words, with my public key, you could send me a secret message that only I could read.

In signing, the public key can be used for another purpose: to verify (with an extremely high degree of mathematical probability) that a “signed” piece of data came from me. Or, to be more specific, could only have come from someone with access to my private key. Which, hopefully, is just me.

In a nutshell, that’s what signing is. Even without actually encrypting it, I can take a chunk of data, run it through a very complex mathematical process to “sign” it with my unique private key, thus generating a second chunk of data called a “signature” that could (statistically speaking) only have come from that specific combination of data chunk and my private key.

Anyone with that signature and my public key can then be almost 100% sure that data came from me, and that it was not modified by any third-party along the way. The data could’t have any virus or vulnerability injected into it, because then the signature would no longer match the data.

So, signing allows us to, with very high confidence, ensure that we are who we say we are, and that the data we produce really came from us. Code-signing, then, is simply applying that signing process to executable code like a Mac app. If I try to start up an app, the operating system can validate that the app’s signature is valid, and perhaps also that it is the signature of a known, trusted developer. If it doesn’t pass muster, the OS can refuse to run the application.

Which brings me to Gatekeeper.

The role of Gatekeeper

The iOS devices (iPhone and iPad) effectively have had a Gatekeeper built into them since their very first release. When we write an iOS app, we sign it, then send it to Apple to review. Apple can validate the signature to ensure that it hasn’t been tampered with — that it really came from us — and then it goes into the app review process.

If the app passes review, it is then signed again by Apple, and posted to the App Store. Since Apple is the only entity able to sign App Store applications, iOS will simply refuse to run any app that doesn’t have Apple’s signature — it obviously didn’t come from the App Store. (If you “jailbreak” an iOS device, this is the security check you are bypassing. You are lobotomizing iOS so that it will merrily run “unsigned” code from any source. As you can hopefully tell by now, this has both benefits in terms of flexibility and very significant risks in terms of security.)

But how to bring this level of security to Mac OS, which has always allowed unsigned code from any source to run more-or-less without restriction?

The simplest thing Apple could have done would have been to make the Mac App Store the sole source for Mac apps, in the same way the App Store is the sole source for iOS apps, shutting off every other app distribution venue in the process. While this would have immediately solved the problem, you would have seen developers’ heads bursting into flame and flying across the room in rage. Why?

Although security is a vital feature for Apple, developers, and users alike, being unable to run unsigned code cuts a lot of really great things off at the knees. You wouldn’t, for example, be able to just download and run an open source project unless it had been submitted to and reviewed by the App Store. Highly disruptive software (think Napster or BitTorrent) may have not been able to exist on the Mac platform since it would have been likely to run afoul of Apple’s App Store guidelines. Major vendors such as Adobe and Microsoft might have withdrawn their support for the platform, being unwilling to cede 30% of their revenue to App Store distribution.

So, for a while, there was a great deal of consternation among Mac developers, including this author, that this might be the route Apple would take. In recent years, Apple has shown a trend of following the most hardline possible stance that will benefit users and Apple, often at the expense of developer freedom, and gradually backing in certain affordances (push notifications, for example) as user-impacting problems became evident. So it seemed feasible that we’d wake up one day and Apple would decree that all Mac apps must be sold through the App Store.

But instead, Apple went to considerable effort and expense to find a middle ground.

Controlling Gatekeeper in Mountain Lion

In Mountain Lion, you, the user, have three options:

1. You can let anything run on your system, whether or not it is signed. This is the Mac OS of today. It’s like having a jailbroken iPhone.

2. You can allow only Mac App Store apps to run on your system. This is the most secure option, but you lose the ability to run non-App Store software, which currently includes such products as Microsoft Office and Adobe CS.

3. You can allow only Mac App Store apps or apps signed by a developer. This is the new default.

It’s this third option that is critical. As a developer, I can register for a unique ID which allows me to sign my app but does not require it be sold through the App Store. Users get the benefit of knowing the app came from a trusted source. But I retain the ability to sell my app directly to end users.

If my app were to do something nefarious, my developer ID would get revoked and that would be the end of that. My app would no longer be allowed to run (unless you specifically allowed unsigned apps). As a matter of fact, if you try to launch an unsigned or unvalidatable app on a Mac with Gatekeeper enabled, the default button is “Move To Trash”. Pretty hardcore. Kind of awesome.

It is really quite a nice compromise.

I have a personal flaw in the form of a small conspiracy theorist who lives in my head. He worried that this may have been created as just a temporary stepping stone — like Rosetta for the Intel transition, or Carbon for the OS 9 to OS X transition — and that one day, the Mac App Store-only option might still be enforced.

But I can’t find it in me to disparage this goodwill effort that Apple has undertaken to not turn every third-party developer upside-down with regard to app distribution. To me it’s a great sign that they’re aware and at some level sympathetic to our concerns, while remaining committed to a high-security experience for users.

Further cementing this feeling is the fact that we were invited to a private briefing at Apple about Gatekeeper a week before today’s announcement. Cabel was told point-blank that Apple has great respect for the third-party app community, and wants to see it continue to grow — they do not want to poison the well. I think their actions here speak even louder than their words, though.

One worrisome rift

There remains one thing that is of concern to me. Despite these great strides forward, Apple is walking a dangerous line with regard to features that are only available to App Store distributed apps. The two most prominent examples are iCloud and Notification Center. Cabel asked Apple if, thanks to Gatekeeper and Developer ID, App Store-only features would be eventually be available to signed apps that were not distributed through the App Store. There was some shuffling of feet and a “we have nothing to announce at this time”. It didn’t sound particularly optimistic.

It would be a shame if this trend continues, as it creates an artificial gulf between App Store and non-App Store apps. For example, as things stand today, we won’t be able to offer iCloud syncing in, say, Coda 2, when you purchase it directly from us. Only App Store purchasers would get that feature. Making matters worse is Apple offers us no real facility to “cross-grade” you from a direct purchase to an App Store purchase, should you change your mind.

There’s no real engineering reason that I can think of for this. It seems marketing or money-driven, and I think it’s un-Apple-like to chase the money at the expense of user experience in that manner. We hope they change their minds about that particular facet.

Moving forward

Other than that though, we think Gatekeeper is a bold new feature that should do wonders for the security of your Mac for years to come. Even though their rapid pace of development is at times difficult for us to keep up with, we are excited that Apple continues to aggressively push the envelope when it comes to keeping Mac OS X safe and secure.

\"

(Via Panic Blog.)

Continue reading...

Automator Workflow To Copy Downloaded Music To iTunes and Then Trash It

Posted on: 2012-02-09 07:27:45

I enjoy being lazy and enjoy listening to podcasts. This allows me to be really lazy!

Download the workflow

Instructions:

  1. Unzip the file.
  2. Copy the contents to \~/Library/Workflows/Applications/Folder Actions
  3. Option-click on the Downloads folder and choose Services -\> Folder Actions Setup…
  4. Select the workflow and make sure it is checked:
Continue reading...

Alfred Scripture Lookup for Bible Translations

Posted on: 2011-11-27 21:40:41

Lately I've had a big appreciation in the number of different translations and often find myself wanting to look up a verse very quickly. Here are a handful of easy to use scripture reference custom searches for use with "Alfred":http://alfredapp.com/.

<a href="alfredapp://customsearch/NIV%20Scripture%20Reference/niv/ascii/url=http://www.biblegateway.com/quicksearch/?quicksearch={query}&qs_version=NIV">NIV <a href="alfredapp://customsearch/The%20Message%20Scripture%20Reference/msg/ascii/url=http://www.biblegateway.com/quicksearch/?quicksearch={query}&qs_version=MSG">The Message <a href="alfredapp://customsearch/NKJV%20Scripture%20Reference/nkjv/utf8/url=http://www.biblegateway.com/quicksearch/?quicksearch={query}&qs_version=NKJV">New King James <a href="alfredapp://customsearch/KJV%20Scripture%20Reference/kjv/ascii/url=http://www.biblegateway.com/quicksearch/?quicksearch={query}&qs_version=KJV">King James <a href="alfredapp://customsearch/ESV%20Bible%20Reference/esv/utf8/url=http://www.esvbible.org/{query}">ESV <a href="alfredapp://customsearch/NASB%20Scripture%20Reference/nasb/utf8/url=http://www.biblegateway.com/quicksearch/?quicksearch={query}&qs_version=NASB">NASB

All but the ESV use "BibleGateway.com":http://biblegateway.com as the search site. Also, if you are as detail-oriented as I am, you may want these handy logos to use as well:

Continue reading...

Finally! An HTML to PDF Workflow That Works

Posted on: 2011-11-05 17:56:27

It is a problem that is as old as computers: making the representation of text and data beautiful. At Classy Llama, we have been searching for a way to make the massive amounts of information we work with accessible, easy to manage, and also beautiful. Here is a workflow that we have started using. Perhaps you might find it useful too.

Some Background

What we want is a system that is three things: accessible, consistent, and easy to use. First, accessible means that the means by which documents can be generated must be easily accessible. Adobe InDesign is not accessible in that it is expensive. Plain Text is accessible because you can produce it on any platform. Consistency refers to the quality and ability to reproduce that quality over and over again. InDesign can produce documents of consistent quality because that is what it was designed to do. So can LaTeX for that matter. Lastly, ease of use is paramount because without it, nobody would use it. LaTeX and Illustrator are great examples of items that are not easy to use at all. While Word & Pages are fairly easy to use.

There are many factors that can affect this, but ultimately we know that we needed to settle on two things:

  1. How documents were going to be generated.
  2. Format of the the finished file.

Ultimately, we know that PDF was the only reasonable answer for #2. The answer to #1 gets a little more interesting. That is why we are here!

I really wanted a reason to do a Venn Diagram. So here it is:

\"Venn_Diagram_Selections\"

The Software

When starting off, I really knew in the back of my mind that a workflow that started with HTML and ended with PDF was going to be the best one. Why? Simply because it meets all three requirements. There are only a handful of people in the building who do not know HTML. The ones who do not can be worked around. So, with HTML as the source, how do we get to the PDF?

Giving Safari a Spin

The initial idea was to just generate a good looking file and then print it straight to PDF with Safari:

\"printing_with_safari\"

  1. Make sure backgrounds are enabled.
  2. Turn off the headers and footers.
  3. Save as PDF...

In a pinch, Safari can definitely take an HTML document and make it a solid-looking PDF. But the thing is, we did not want it to look like a printed web page. We wanted it to look professional. Safari lacked some some functionality that we really wanted. Control over headers and footers was something we really had to have. It's not as easy to do in Safari as I had hoped.

What about Firefox?

Firefox was about the same as Safari except that Firefox gives you some more control over the header and the footer:

\"firefox_print\"

This is fine and good, but still too limiting.

PHP, Web Services, & Scripts to the Rescue?

There are several options for building PDF documents. HTML2PDF converts HTML documents to PDF as a PHP library. Others are web services. There are yet more scripts and libraries that provide PDF building as an API inside of PHP. I found other scripts that also claimed to convert HTML to PDFs in a CLI package. None that I tried seemed to work quite right (or at all). More dead ends. At this point, I was about to give up.

We Need an HTML Renderer

The only thing that would really work is if you could find something that rendered the HTML like a browser could. I remember trying Firefox's “Command Line Print Interface,” but to no avail. Surely there was something else. That something else was wkhtmltopdf.

Finally, a Solution!

wkhtmltopdf actually works: a program that contains the webkit rendering system (just like Safari uses) but has been put into a format that specializes in exporting postscript and PDF output of web pages. It is totally designed for this purpose. Finally, a solution that works! Proper headers and footers. Table of contents inside of the PDF and bookmarks in the file. Full use of CSS to control every aspect of the rendering (including custom fonts via font-family and @font-face). A whole slew of command line options that allow you to control paper size, and set nearly every possible thing you would need. So far, I've found in nearly perfect. There have been a couple of gotchas, though.

Little Square Boxes

One of the first things to catch my eye was that occasionally there were little squares in generated documents. They weren't there when the document was printed, but when viewing in Acrobat or Preview, they were definitely visible. After much sleuthing, I discovered that the square boxes were null glyphs that had somehow managed to make their way into the various strings in the document. With a little help from pdftk, those boxes are no longer a problem:

  1. Use pdftk to uncompress the PDF.
  2. Run the resulting file through sed to remove the null glyphs (lines containing ‘Td <0000> Tj').
  3. Use pdftk once more to compress the PDF.

Here is the shell script snippet:

pdftk output.pdf cat output - uncompress | sed '/Td <0000> Tj/d' | pdftk - cat output output.pdf compress

Easier Headers & Footers

The last nagging bit was that we need to be able to have document versions and potentially other info that can be easily updated. The way that wkhtmltopdf is set up by default is that the headers and footers have a specific set of variables that come to them. Mainly just page number information and information about the current “section” of the document you are in. But versioning the document did not seem to be supported out of the box. What I wanted to be able to do was set the version number of the document in the document itself. That would be ideal.

One of the awesome and super-extensible things about wkhtmltopdf is that the headers and footers can be specified as source files. Source files means URLs. URLs mean request variables. The page number information already gets passed as get variables to the document. Those are then parsed out via JavaScript. So, I gave it a shot:

wkhtmltopdf \\ -s Letter \"untitled.html\" \\ --header-html \"header.html?something=value\" \\ --footer-html \"footer.html?something=value\" output.pdf

Which did not work. Passing the query arguments meant that it wanted a real URI. So since these were local files, why not try:

THISDIR=`pwd` wkhtmltopdf \\ -s Letter \"untitled.html\" \\ --header-html \"file://$THISDIR/header.html?something=value\" \\ --footer-html \"file://$THISDIR/footer.html?something=value\" output.pdf

Which worked perfectly. Still need to get the information about the document from the source HTML into the header and footer files. Now PHP finally comes to the rescue with this little snippet:

EXTRAVARS=`php -r \"echo urldecode(http_build_query(get_meta_tags('untitled.html')));\"`

This little guy takes this (from the source HTML document):

It's important to note that the spaces must stay intact. wkhtmltopdf does not decode them for you. Just escape them in your command line arguments and it will be fine. You will also need to add these variable names into the stock header and footer template that wkhtmltopdf gives you. It will look like this:

<script> function subst() { var vars={}; var x=document.location.search.substring(1).split('&amp;'); for (var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);} var x=['title','version','project','client','frompage','topage','page','webpage','section','subsection','subsubsection']; /* Added new variables here */ for (var i in x) { var y = document.getElementsByClassName(x[i]); for (var j=0; j
Page of

A little bit of bash scripting and now we have something like this:

#!/bin/bash # EDIT THIS - This points to your source file HTMLFILE=\"my_pretty_file.html\"

Where are we?

THISDIR=$(pwd -P)

Grab the title of the HTML document from the source.

RAW_TITLE=grep -e '' \"$HTMLFILE\" | sed -E 's/<\\/?[^>]+>//g' ENTITY_TITLE=php -r \"echo html_entity_decode('${RAW_TITLE}');\"

Build the extra variables to add to the footer and header.

EXTRAVARS=php -r \"echo urldecode(http_build_query(get_meta_tags('$HTMLFILE')));\" EXTRAVARS="${EXTRAVARS}&title=${RAW_TITLE}"; # Add the title

Generate the document.

wkhtmltopdf -q \ --no-pdf-compression -s Letter \ --header-html "file://$THISDIR/header.html?$EXTRAVARS" \ --footer-html "file://$THISDIR/footer.html?$EXTRAVARS" - | sed '/Td <0000> Tj/d' > "$ENTITY_TITLE.pdf"

Final Thoughts

This is a work in progress, but it is now a viable option for generating beautiful, consistent documents from HTML. You could have a shared server that would host your templates, CSS, fonts, etc and the only tools necessary would be the scripts, wkhtmltopdf, pdftk, and your source file. Not bad for a free setup.

With something like pandoc, you need not be limited to just HTML. You could easily modify the script above to take your source file and push it through pandoc and then pass it on down to wkhtmltopdf. The possiblities are limitless. So, what are you waiting for? Go try it out!

Update...

Upon further use, I discovered an unintended side-effect: use of pdftk causes the bookmarks in the file to disappear. However, it turns out that by passing the --no-pdf-compression flag removes the need to decompress the PDF file before removing the extra characters.

I'm still looking for a way to append extra files (PDF, HTML, or otherwise) into the file and utilize bookmarks. Any thoughts?

Continue reading...

Attending x.commerce Innovate Developer Conference

Posted on: 2011-10-10 14:02:09

Tomorrow, several other "Classy Llamas":http://classyllama.com/) and I will be heading to San Francisco to attend the "x.commerce":http://x.com/ "Innovate Developers Conference":http://www.innovate-conference.com/! This is very exciting for a couple of reasons:

The idea of x.commerce is very ambitious. It is the first platform that aims to be first full-spectrum, end-to-end eCommerce platform. It's exciting to be a part of something like that.

Secondly, Magento will be testing their "Beta Developer Certification Exam":http://www.innovate-conference.com/ I've been a big supporter of this and it will be awesome to be one of the first to take this new exam and become a Certified Magento Developer!

Lastly, it will be great to meet & greet the other Magento developers and partners.

We'll be updating our "Classy Llama blog":http://classyllama.com/blog/ with updates as we can!

Continue reading...

God & Us: Father & Son

Posted on: 2011-07-24 15:13:30

Watching my son gives me insight into how our own relationship between our heavenly father and us looks.

It is hard to count the number of times he has done something that I obviously wished him not to do -- even while under constant supervision. He knows that what he does goes against my wishes. When I call him he does not come to me with childlike innocence... he quickly stops what he is doing and looks at me with these eyes that seem to say "I was not doing what you think I was doing!" Whoever says children are full of innocence and good must not have met my child! He knows full that his actions are not what I desire and when caught in the act he quickly tries to hide his actions.

He definitely gets that from me.

How many times have I done something and then half a moment later realized that our Father is watching over me? I'd do good to, like my son, quickly throw the object with which I've taken an interest in as far away as possible. Sadly, the son trumps the father on this one. The one think thankfully he has not yet learned is pride!

I thank God that he disciplines me just like I discipline my son.

Continue reading...

Arrays With UTF-16 Strings Will Give You Headaches

Posted on: 2011-05-19 10:13:38

Today I was working with some CSV files using PHP's "fgetcsv":http://php.net/fgetcsv and "array_search":http://php.net/array_search functions.

I had a row like this:

cus_no,first_name,last_name,full_name,fax_no,phone_no,e_mail

Looks normal, right?

But when I was running array_search('cus_no', $headerRow) it would return FALSE. What is the deal?

Digging deeper, "print_r()":http://php.net/print_r returned exactly what expected:

Array
(
    [0] => cus_no
    [1] => first_name
    [2] => last_name
    [3] => full_name
    [4] => fax_no
    [5] => phone_no
    [6] => e_mail
)

Okay. Scratch head. Sip coffee. Deep breath. What is going on here?!

Lets see what "var_dump()":http://php.net/var_dump says:

array(7) {
  [0]=>
  string(12) \"cus_no\"
  [1]=>
  string(21) \"first_name\"
  [2]=>
  string(19) \"last_name\"
  [3]=>
  string(19) \"full_name\"
  [4]=>
  string(13) \"fax_no\"
  [5]=>
  string(17) \"phone_no\"
  [6]=>
\" string(15) \"e_mail
}

Whoa. That is strange. Why is that quote at the beginning of the line? Check eyes. Sip coffee.

"var_export()":http://php.net/var_export had something much different to report:

array (
  0 => 'c' . \"\\0\" . 'u' . \"\\0\" . 's' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'o' . \"\\0\" . '',
  1 => '' . \"\\0\" . 'f' . \"\\0\" . 'i' . \"\\0\" . 'r' . \"\\0\" . 's' . \"\\0\" . 't' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'a' . \"\\0\" . 'm' . \"\\0\" . 'e' . \"\\0\" . '',
  2 => '' . \"\\0\" . 'l' . \"\\0\" . 'a' . \"\\0\" . 's' . \"\\0\" . 't' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'a' . \"\\0\" . 'm' . \"\\0\" . 'e' . \"\\0\" . '',
  3 => '' . \"\\0\" . 'f' . \"\\0\" . 'u' . \"\\0\" . 'l' . \"\\0\" . 'l' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'a' . \"\\0\" . 'm' . \"\\0\" . 'e' . \"\\0\" . '',
  4 => '' . \"\\0\" . 'f' . \"\\0\" . 'a' . \"\\0\" . 'x' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'o' . \"\\0\" . '',
  5 => '' . \"\\0\" . 'p' . \"\\0\" . 'h' . \"\\0\" . 'o' . \"\\0\" . 'n' . \"\\0\" . 'e' . \"\\0\" . '_' . \"\\0\" . 'n' . \"\\0\" . 'o' . \"\\0\" . '',
' . \"\\0\" . '',0\" . 'e' . \"\\0\" . '_' . \"\\0\" . 'm' . \"\\0\" . 'a' . \"\\0\" . 'i' . \"\\0\" . 'l' . \"\\0\" . '
)

Whoa! Now that is strange. Looks like there are two characters per... wait a sec!

!sites/nickvahalik.com/files/crazy_csv_file.jpg!

Should have known. UTF-16. Friends don't let friends use non-multibyte functions on multibyte datas! It was putting null characters into the string internally? Who knows. I'm sure the PHP source code would probably enlighten me on this. But no time! Those CSV files aren't going to read themselves!

Update: My fellow llama Jonathan Hodges noticed something I failed to see: The length of the strings in var_dump() are double the size they should be:

array(7) {
  [0]=>
  string(*12*) \"cus_no\"
  ...
Continue reading...

Moving the Cursor in OSX's CLI

Posted on: 2011-05-16 20:58:33

Just found this "great little article over at superuser.com":http://superuser.com/questions/131938/how-to-skip-words-in-os-x-terminal about how you can use meta-b and meta-f to use backwords and forwards by words in the CLI. Since there is no meta key, you have to use ?-b and ?-f (escape as meta).

Optionally, you can set the option key as meta in Terminal's settings:

!http://files.classyllama.com/dec8e77a/terminal-settings-meta-key-20110516-205752.jpg!

Continue reading...

Easily View Magento Layout with Alan Storm's Layoutviewer

Posted on: 2011-05-16 16:22:56

<a href="http://alanstorm.com/">Alan Storm has a great module called <a href="http://alanstorm.com/2005/projects/MagentoLayoutViewer.tar.gz">Layoutviewer that is great for front-end developers.  It allows you to see the layout that Magento will use to render a page. This can be useful to debug what layout updates have been applied to a page.  One way or another, it usually ends up in most of my development sites.

Here is a nice little shell script you can copy-and-paste or download to easily add it to your project:

#/bin/bash VIEWER_HTTP_DOWNLOAD=\"http://alanstorm.com/2005/projects/MagentoLayoutViewer.tar.gz\"

If we are in the root, then we need to go into app/code/local.

if [ -f "index.php" ]; then cd app/code/local; fi

curl -so - $VIEWER_HTTP_DOWNLOAD | tar xvzf -

( cat <<'ConfigFile'

true local

ConfigFile ) > ../../etc/modules/Allanstormdotcom_Layoutviewer.xml

Also, here is a little bookmarklet that you can use to show the formatted XML for a page using the installed module:

<a href="javascript:window.location.href = window.location.protocol + '//' + window.location.hostname + window.location.pathname + (window.location.search=='' ? '?showLayout=page&showLayoutFormat=text' : window.location.search + '& showLayout=page&showLayoutFormat=text');">Display Layout

Just drag it to your bookmarks bar!

You can also download the attached shell script. It will (from the htdocs folder for your Magento site) download the layoutviewer module.

Continue reading...

Leaps, Blessings, and Springfield, Missouri

Posted on: 2011-01-09 20:52:35

Several months ago I started looking for a new job. Not one of those desperate "i'll-take-the-first-thing-that-looks-great" kind of search. A pleasure search. One of those "where-would-I-absolutely-love-to-work" kind of searches. Applications slowly trickled out. Resumes were written, tweaked, revised, and sent. LinkedIn recommendations were written, etc. I probably sent 2 or 3 resumes per week for several weeks. Only to places that would have been really fun to work (or at least I thought would have been fun to work for.)

The job market here in Temple, TX is not what you'd call "jumpin'" for people in my field. Austin, Dallas, and Houston are really the places to be unless you want to freelance. But freelancing is just not something I could really do. It has never really felt like my calling. It felt like it a couple of times but I honestly suck as a freelancer. I hate asking people for money and I don't like keeping track of hours. My point is that ultimately there were two choices: move some place or commute.

Having commuted something like 4 years for an hour and a half each day, I can easily tell you that commuting is not my first choice. If gas were 50% of what it was... it would be easier to consider. Having a small child at home makes me want to maximize my time even more. There are good things about commuting: audio books, lectures, talk radio, tunes, etc. But all of those pale in comparison to spending time with my family. Commuting is eh.

Moving was something that I was initially opposed to doing. Proximity to friends & family, a wonderful church and small group, along with so many other things that makes roots hard to pull up was definitely a consideration that had to be weighed in the search for a new job. My stepdaughter has a year and a half left of high-school here, my in-laws are 30 minutes away. There were plenty of reasons to stay here.

But there are definitely more reasons for looking. It is a long story, and one that isn't really worth telling in depth. The short of it really is that bonds of trust were broken, great initiatives and ideas were discarded, and the desire to give 110% had slowly waned. Granted, I think we all go into slumps and drop below the 90% mark. It just happens. But when the things you help to build and felt were good and right are stripped away and discarded like last week's leftovers: it hits you like a train. A train that you can see coming but the world is moving in slow motion... and your feet don't want to move.

It leaves you with two choices: stay unhappy and collect that paycheck or get out of the way.

Well, we're getting out the way. It's not easy to look a nice check every month and just say "eh, I can do with you!" Not very easy at all. Especially since Sarah is not gainfully employed. But what is it? A means to an end? Proverbs 11:28 says "Money cannot be trusted in for it will lead to one's downfall." Man. My downfall? The strange thing is, just like that "train" I can see it coming. Bad moods, stress, and all sorts of bad things. They lead to worse things. I had to get out... and trust in the Lord.

Sometime in between all of this I saw an ad on Facebook for a job at "Classy Llama Studios":http://classyllama.com. They were looking for a PHP Expert. Sure, no problem. So the resume got sent, and a couple of days later a call was made to follow-up. Good thing that call was made because apparently someone had overlooked my resume! Next thing I know, I'm driving to Springfield, MO for an interview. I went from not knowing if there was another job out there for me to "Oh man, this could be awesome!" in no time.

I had prayerfully considered the idea that perhaps God had wanted me to stay in my current job. To do good work, to be kind to those who had hurt me, and to carry on what was started by those before me. However, even those around me started picking up on the fact it would be harder to do than we expected. Things kept getting more stressful, and there did not appear to be an end in sight. I felt a little like David being pursued by Saul. But whereas David has a kingdom waiting for him on the other side, more and more it seemed like there was nothing waiting for me on the other side. I had to get out. But in order to get out, a lot of trust was needed because what was coming was not what we expected.

And so trust we did. We had to put our house up for sale, start packing, find a place to live, come up with a new budget, and gracefully leave my current position. From the very start we knew that we could not do all of this on our own. But as we were talking about the offer that Class Llama sent me, I realized that we were not talking about "if" I would take it... but how we could make it work. It was a "yes" the moment we got it. But there was so much we were worried about.

But as this story is unfolding, it is wholly apparent that our trust has been graciously rewarded. The Lord's hands have been felt in our lives since we began this process! The Lord provided someone who really wants to buy our house. The Lord provided free boxes for moving. The Lord provided a wonderful place to move. We have been blessed in finding a home for Fez, my cat. The list goes on and on: support from our small group, families, and friends, plenty of time to finish things here, Sarah being able to do some contract work from home...

To top it all off, I'll get to work with some awesome people, doing awesome things... with a purpose. The icing on the cake is that two of Sarah's kids live near Springfield, so we will get to see them more often as well! The Lord has truly blessed us. I am so excited about this new job and we are excited about starting the next chapter of our lives in Springfield, Missouri.

Continue reading...