Feeds

108553 items (868 unread) in 22 feeds

CNN CNN
MSNBC MSNBC
PHP PHP
Deals Deals
Tech Tech
Web Development Web Development
CNN Money CNN Money
Frugal Blogs Frugal Blogs

Items by Jeffrey Way

Nettuts+

  • Permalink for 'Are jQuery Users Fools?'

    Are jQuery Users Fools?

    Posted: November 27th, 2011, 3:00pm MST by Jeffrey Way

    We should get this out into the open. There seems to be a commonly held belief that jQuery users are ignorant, and, more often than not, designers. Where did this come from, and is it true?

    Roots

    The JavaScript community wasn’t nearly as vibrant and passionate as it is today.

    Let’s take a trip down memory lane; we’ll rewind the clock several years – pre jQuery days. The JavaScript world was a very different scene back then. The community wasn’t nearly as vibrant and passionate as it is today. Sure, back then, there were a few libraries, like Prototype; but they never managed to grab the regular user spotlight the way that jQuery soon would. At that time, JavaScript was a widely hated language. Sometimes, it’s easy to forget that there were times when developers refused to take the necessary time to …ya know… learn JavaScript! Instead, they’d simply copy and paste their way, hoping to keep from getting that nasty JavaScript stain on their pants.

    The DOM

    What you mean is, “I hate the DOM API.”

    What these copy and paste addicts (I was one of them) didn’t realize is that, when you say, “I hate JavaScript,” what you really mean (whether you realize it or not) is, “I hate the DOM API.” No one can be blamed for feeling that way. Especially back in those days, when even IE5 support was in effect, things could get a bit nasty. Browser implementations of the DOM were the culprit; not the JavaScript language. This is due to the fact that there really wasn’t any DOM specification. As a result, browsers sort of winged it as best as they could! We have innerHTML not because of a specification, but because the Internet Explorer team decided to just throw it in there (at which point the other browser vendors reverse engineered it, and implemented it into their own browsers). But the JavaScript language, as a whole, is solid.

    In fact, many folks, including myself, would go as far to say that, as a language, JavaScript is really quite beautiful.

    jQuery

    Around that time, jQuery entered the atmosphere, and began taking the development community by storm. While other libraries like Prototype still retained a certain level of complexity and confusion for newcomers, jQuery was ridiculously easy to grasp, thanks to the fact that everything is accessible, via the jQuery object (something that it’s, ironically, often criticized for).

    Need to apply a class? Easy; doing so is tailor made for designers. jQuery allows you to use the CSS selectors you already know to query the DOM.

    $('#container').addClass('ahh-yeah');
    

    Fun Fact: Technically, though jQuery popularized the idea of a CSS selector engine, it was largely based on work by Dean Edwards.

    And then, at some point, the timeline skewed into this alternate reality…

    It literally couldn’t be simpler. By abstracting away complex code and browser quirks, developers could get back to doing what was important: creating websites and applications.

    While jQuery’s community grew in leaps and bounds, the library, itself, also continued to mature and take shape. The world was peachy.

    And then, at some point, the timeline skewed into this alternate reality (okay, not as Doc Brown as that), where, suddenly, if you labeled yourself as a proud jQuery user, certain members of the JavaScript community would consequently feel the need to stereotype you as an ignorant “designer” (regardless of whether you were or not) – certainly not a “JavaScript Developer.” How did this happen? JavaScript developers don’t use jQuery?

    The Burden of Popularity

    Everyone has an opinion about the spotlight.

    It’s only natural that, once you reach a certain – for lack of better words – popularity, you open yourself to incredible amounts of scrutiny. Everyone has an opinion about the spotlight, it seems. For example, you’ve no doubt heard endless criticism of Catholicism. “They worship statues.” Is that the only religious body with questionable history? Surely not; but it’s the largest. The United States is one of the most powerful countries in the world. Naturally, everyone has an opinion. “Americans are ignorant and fat.” Ignore the good, and spotlight the bad.

    jQuery is the most popular JavaScript library, by a landslide. Again, everyone has an opinion. I’ve read countless criticisms – everything from what it doesn’t do, to the structure of the code base. However, perhaps the biggest criticism of jQuery comes from a simple truth: its users, as an average, are less experienced with vanilla JavaScript, when compared to, say, Mootools. While some consider this to be a downside, I honestly view it as a strength – in an odd way.

    The fact that jQuery has many less-experienced users is not its downfall; it’s a testament to its appeal.

    jQuery Users Don’t Know JavaScript!

    This is the argument you’ll hear more than any other. Again, a testament to jQuery, many people learn jQuery before vanilla JavaScript. There have been countless debates on whether this is a good thing or not. In fact, these sorts of discussions extend to all abstractions.

    • Should designers use CSS preprocessors and frameworks, like Sass and Compass, respectively, before learning the ins and outs of CSS?
    • Is it okay for a Ruby developer to use CoffeeScript without first learning JavaScript?
    • Should you use Modernizr before learning how to write a single feature test?
    • Is it okay to use CodeIgniter if you’ve only just learned PHP?

    Personally, I feel that those who demand that newcomers first learn JavaScript before moving on to jQuery are missing one thing: JavaScript and the DOM are scary! If you throw the ES5 specification at them, they’re going to have a heart attack, unless they have a real interest in becoming a JavaScript developer. Many people simply need to add a few effects to their websites. We can’t always master everything. Are they bad people for choosing their priorities? Of course not.

    JavaScript and the DOM are scary!

    Compare this to simple Math. When you first learned how to add 2 + 2, did you do it the official way? I sure didn’t; I used my fingers. I bet you did too. Though it’s a huge simplification of the issue, is jQuery not the same way? It provides new JavaScript users with a simple and exciting entry point. Do you honestly expect them to learn about closures and objects and global variables before they even learn how to do something fun? Come, come, now.

    The strict, “Learn it the right way, or you’re a fool” viewpoint is naive, and doesn’t take into account the various learning styles that we all have.

    I view jQuery as bait. Hold it over the user’s head, get them really excited by it, and then, when they feel ready, they almost always move on to learning more vanilla JavaScript.

    jQuery Users Write Poor Code

    Once again, this is a massive generalization. Some of the biggest and most influential companies in the world use jQuery. But yes, there are lots of beginners who are still in the process of learning. Oh well; it happens. Poor code exists in every language. I’ve written a good bit of it myself, I’m proud to say! The best we can do is, rather than scorn them publicly, offer advice and tips when we can. We’re all learning. Do we really need to attack some, because they have different priorities and skill-sets?

    With popularity, comes the potential for bad advice.

    jQuery managed to generate this incredibly passionate community – from the hardcore JavaScript developers down to the designers who were amazed by how easy it was to get the job done. This passion subsequently lead to countless jQuery tutorials by community members – both good and bad. While still learning jQuery (something I’m still doing), I can guarantee that I offered some terrible advice at one point or another. It’s not too dissimilar to the PHP community. With popularity, comes the potential for bad advice.

    The Ruby Community

    This sort of pointless teaching almost hurts the community.

    In the Ruby community, there’s an interesting dynamic. Tutorials are, to generalize things, written by the veterans. In other words, if you’re going to write a Ruby on Rails article or book, you should fully expect extreme scrutiny. If you don’t have a massive level of experience, don’t you dare write about it. In some ways, this is a strength. As a student, you can more easily rest assured that what you’re learning is correct. On the other hand, PHP tutorials are all over the place. Writers sometimes focus on the insignificant, and ignore the important. You’ll often find best practice PHP tutorials, which describe whether or not it’s faster to use single quotes or double quotes. Of course, this sort of pointless teaching almost hurts the community.

    What Do You Prefer?

    It’s an interesting thing, I must say. What do you prefer? A smaller, passionate base, or an incredibly popular one, consisting of all skill levels? There’s certainly pros and cons to each.

    It’s undeniable that many of us feel a need to be trail blazers. Remember when parents began signing up for Facebook? Critics widely declared that the end of Facebook was near. Once you sacrifice exclusivity for wide appeal, people instinctively begin searching for the next thing. But that didn’t happen. The same is true for jQuery. Sure, some users have moved on to more comprehensive frameworks, like Dojo. But that’s to be expected, and should be a badge of honor for jQuery. For many, the learning cycle goes like this:

    • Learn jQuery; get excited.
    • Realize that you have no clue what this refers to in different situations. Learn JavaScript, and incrementally improve your old jQuery code.
    • (Optional) Advance your skills to the point where you need a more comprehensive framework for building large applications. Begin reviewing additional tools, such as Dojo.

    Is that so bad?

    Real Deadlines

    It’s not like we’re coding in binary here, folks.

    There will always be the advocates who suggest that you shouldn’t use a library – period. Given the current state of JavaScript and the DOM, though, I honestly feel that this is bad advice – particularly for newcomers. They shouldn’t be expected to wrestle with frustrating browsers inconsistencies so early in the learning process. And, many times, abstractions are a very good thing! It’s not like we’re coding in binary here, folks. When you use jQuery, or any other popular library, you’re benefiting from countless tests, bug fixes, and the best minds in the industry.

    Now, certainly, you’re not required to use somebody else’s framework. Create your own library, if you have the ability; that works too! The goal is to:

    • Normalize browser quirks
    • Write less code
    • Benefit from as many minds as possible
    • Meet real deadlines, and get the job done

    jQuery is not “a designer’s library,” but it appeals to designers. It’s not as class-based as other libraries, but this makes the entry point for newcomers far more painless. So what we end up with is a library that helped reignite the JavaScript community. It’s simple enough to appeal to first-timers, and powerful enough to be used by the largest companies in the world. Why exactly is it being criticized again?


  • Permalink for 'How to Inject Custom HTML and CSS into an iframe'

    How to Inject Custom HTML and CSS into an iframe

    Posted: November 21st, 2011, 2:59pm MST by Jeffrey Way

    Ever been to a site like JSBin, where you can write HTML, CSS, and JavaScript, and then see the results in a panel to the right? An iframe is how we can accomplish this task. In today’s quick tip, I’ll show you how to inject HTML and CSS into an iframe.

    Select 720p for optimal viewing.


  • Permalink for 'Quick Tip: The Awesome Details Element'

    Quick Tip: The Awesome Details Element

    Posted: November 17th, 2011, 5:16pm MST by Jeffrey Way

    One of my favorite new HTML5 tags, which has only recently been integrated into Chrome (as of version 12), is the details element. I’ll show you to use it in today’s quick tip.

    What Does the details Tag Do?

    It essentially allows us to show and hide content with the click of a button. You’re surely familiar with this type of effect, but, up until now, it had always been achieved with JavaScript. Imagine a heading with an arrow next to it, and when you click on it, additional information below becomes visible. Clicking the arrow again hides the content. This sort of functionality is very common in FAQ pages.

    Here’s a two minute example of this sort of effect. (Type Control + Enter to process the JavaScript.)

    The details element allows us to omit the JavaScript entirely. Or, better put, it eventually will. Browser support is still a bit sparse.

    image An Example

    So let’s dive in and learn how to use this new tag. We begin by creating a new details element.

    <details>
    
    </details>
    

    Next, we need to give it a title, or summary of the content within.

    <details>
    	<summary> Who Goes to College? </summary>
    </details>
    

    By default, in browsers that understand the details element, everything within it — other than the summary tag — will be hidden. Let’s add a paragraph after the summary.

    <details>
    	<summary> Who Goes to College? </summary>
      <p> Your mom. </p>
    </details>
    
    Default Display

    Go ahead and try the demo out in Chrome 12 or higher (as of November 17th, 2011).

    Okay, let’s do something a bit more practical. I want to display various Nettuts+ articles using the details element. We first create the markup for a single article.

    <details>
       <summary>Dig Into Dojo</summary>
       <img src=" [d2o0t5hpnwv4c1.cloudfront.net] alt="Dojo" />
       <div>
          <h3> Dig into Dojo: DOM Basics </h3>
          <p>Maybe you saw that tweet: “jQuery is a gateway drug. It leads to full-on JavaScript usage.” Part of that addiction, I contend, is learning other JavaScript frameworks. And that’s what this four-part series on the incredible Dojo Toolkit is all about: taking you to the next level of your JavaScript addiction.
         </p>
       </div>
    </details>
    
    image

    Next, we’ll give it just a touch of styling.

    body { font-family: sans-serif; }
    
    details {
      overflow: hidden;
      background: #e3e3e3;
      margin-bottom: 10px;
      display: block;
    }
    
    details summary {
      cursor: pointer;
      padding: 10px;
    }
    
    details div {
      float: left;
      width: 65%;
    }
    
    details div h3 { margin-top: 0; }
    
    details img {
     float: left;
     width: 200px;
      padding: 0 30px 10px 10px;
    }
    
    image

    Please note that I’m showing you the open state for convenience, but, when the page loads, you’ll only see the summary text.

    If you’d prefer to be in this state by default, add the open attribute to the details element: <details open>

    Styling the Arrow

    It’s not quite as straight-forward to style the arrow itself as we might hope. Nonetheless, it is possible; the key is to use the -webkit-details-marker pseudo class.

    details summary::-webkit-details-marker {
      color: green;
      font-size: 20px;
    }
    
    Styling the arrow

    Should you need to use a custom icon, possibly the easiest solution is to hide the arrow (using the pseudo class above), and then either apply a background image to the summary element, or use the :after or :before pseudo elements.

    View the final project.

    Conclusion

    It’s certainly a simple effect, but it sure is nice to have such a common feature built-in. Until we can reliably use the details element across all browsers, you can use this polyfill to provide fallback support. One final note: at the time of this writing, there doesn’t seem to be a way to toggle the contents with a keyboard. This could potentially present some accessibility issues.


  • Permalink for 'An Update on Nettuts+ Prefixr'

    An Update on Nettuts+ Prefixr

    Posted: November 9th, 2011, 9:46am MST by Jeffrey Way

    Many of you might be aware that we recently launched a helpful web service, called Nettuts+ Prefixr. Thankfully, the tool has come a long way since the initial launch, as I’ve squashed countless bugs, and added some neat new features. I’d like to give you a quick rundown on the current state of the tool, as well as how to use it.

    Wait – What is Prefixr? Prefixr

    Prefixr takes all of those pesky CSS3 prefixes that we must type over and over, and does away with them! If you create your stylesheets using the official syntax, you may then, at deployment, run your clean stylesheet through Prefixr, and it’ll instantly update your stylesheet to include every required prefix.

    This way, you don’t have to deal with remembering whether or not a particular CSS3 property requires a -ms prefix or not. That knowledge is built into Prefixr.

    Let’s review a quick example. Below, I have some scattered CSS that is badly in need of updating. Notice that, in some places, we’ve only declared a -moz prefix; in other areas, we’ve used the official syntax, etc.

    .box {
       opacity: .5;
    }
    
    .container {
       box-shadow: 20px;
       -moz-transition: box-shadow 2s;
       -webkit-border-radius: 4px;
       animation: slide 1s alternate;
       background: linear-gradient(top, #e3e3e3 10%, white);
    }
    
    @-webkit-keyframes "slide" {
       0% { left: 0; }
       100% { left: 50px; }
    }
    

    Copy the code above, and paste it into Prefixr. In return, you’ll receive:

    .box {
       -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";
       filter: alpha(opacity=50);
       opacity: .5;
    }
    
    .container {
       -webkit-box-shadow: 20px;
       -moz-box-shadow: 20px;
       box-shadow: 20px;
    
       -webkit-transition: box-shadow 2s;
       -moz-transition: box-shadow 2s;
       -o-transition: box-shadow 2s;
       -ms-transition: box-shadow 2s;
       transition: box-shadow 2s;
    
       -webkit-border-radius: 4px;
       -moz-border-radius: 4px;
       border-radius: 4px;
    
       -webkit-animation: slide 1s alternate;
       -moz-animation: slide 1s alternate;
       -ms-animation: slide 1s alternate;
       animation: slide 1s alternate;
    
       background-image: -webkit-gradient(linear, left top, left bottom, color-stop(10%, #e3e3e3), to(white));
       background: -webkit-linear-gradient(top, #e3e3e3 10%, white);
       background: -moz-linear-gradient(top, #e3e3e3 10%, white);
       background: -o-linear-gradient(top, #e3e3e3 10%, white);
       background: -ms-linear-gradient(top, #e3e3e3 10%, white);
       background: linear-gradient(top, #e3e3e3 10%, white);
    }
    
    @keyframes "slide" {
     0% {
        left: 0;
     }
     100% {
        left: 50px;
     }
    
    }
    
    @-moz-keyframes "slide" {
     0% {
        left: 0;
     }
     100% {
        left: 50px;
     }
    
    }
    
    @-webkit-keyframes "slide" {
     0% {
        left: 0;
     }
     100% {
        left: 50px;
     }
    
    }
    
    @-ms-keyframes "slide" {
     0% {
        left: 0;
     }
     100% {
        left: 50px;
     }
    
    }
    

    Wow – that’s a lot of duplicate styling. But, unfortunately, it’s necessary at this point in time. If you want your web applications to be as consistent as possible from browser to browser, you need to use these various prefixes. However, as you can imagine, this can quickly bloat your code. That’s why Prefixr is so helpful!

    Create your stylesheets using the official syntax, and then run it through Prefixr when you deploy, or when you need a conversion.

    I Don’t Want to Copy and Paste into Prefixr

    No worries! I don’t either. Visiting Prefixr.com is only one way to update your stylesheets. I much prefer to use it within my favorite code editor. Thanks to various users, there are a handful of plugins and scripts available for the most popular editors. For example, as a Sublime Text user, I personally use Will Bond’s “Sublime Prefixr” plugin, which works wonderfully.

    Now, I never to have to manually visit Prefixr and copy and paste my stylesheet. I simply select the bit of CSS that I wish to optimize, and type ctrl+alt+x on Windows and Linux, or cmd+ctrl+x on OSX.

    Editors List

    Refer below for the current list of supported editors.

    Editors TextMate Commands

    There are countless TextMate users out there; let’s create a command that will run a selection through Prefixr, and place the result in the clipboard. Within TextMate, browse to the Bundle Editor, and create a new command.

    Bundle Editor

    Paste the following into the “Command” textarea. This will take the selected text, run it through Prefixr, and copy the response to your clipboard. Next, assign an activation key, and you’re all set! This is helpful if you’d prefer to store the Prefixed results in a separate stylesheet.

    curl -sSd "css=$TM_SELECTED_TEXT" " [prefixr.com] | pbcopy
    

    Or, if you’d prefer the result to be compressed, modify the command, like so:

    curl -sSd "css=$TM_SELECTED_TEXT&compress_option=true" " [prefixr.com] | pbcopy
    

    Now, if your stylesheet displays:

    .box {
    	border-radius: 5px;
    }
    

    Select the stylesheet, type the activation key that you assigned, and the following should now be stored in your clipboard (assuming you use the compress option).

    .box{-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;}
    
    Can I Use Variables?

    Prefixr isn’t the same type of preprocessor as Less, Stylus, or Sass. I love those – Sass and Stylus particularly. Prefixr is instead for the folks who dislike the idea of using them. That said, variables do come in handy, so if you’d like to use them in Prefixr, it will automatically update your stylesheets. For example:

    @variables {
      site_width: 960px;
    }
    
    .container {
       width: var(site_width);
    }
    

    Run it through Prefixr, and we get:

    .container {
       width: 960px;
    }
    

    It’s important to note that this is entirely an optional feature. If you feel that variables complicate CSS, then don’t use this feature!

    Requests?

    Nettuts+ Prefixr is under active development, so if you notice a bug or would like a new feature to be implemented, either leave a comment below, or click on the “Feedback” button at Prefixr.com.


  • Permalink for 'How to Work with GitHub and Multiple Accounts'

    How to Work with GitHub and Multiple Accounts

    Posted: November 2nd, 2011, 2:39pm MDT by Jeffrey Way

    So you have a personal GitHub account; everything is working perfectly. But then, you get a new job, and now need to have the ability to push and pull to multiple accounts. How do you do that? I’ll show you how!

    Prefer a Screencast?

    Choose 720p for the best picture. Step 1 – Create a New SSH Key

    We need to generate a unique SSH key for our second GitHub account.

    ssh-keygen -t rsa -C "your-email-address"
    

    Be careful that you don’t over-write your existing key for your personal account. Instead, when prompted, save the file as id_rsa_COMPANY. In my case, I’ve saved the file to ~/.ssh/id_rsa_nettuts.

    Step 2 – Attach the New Key

    Next, login to your second GitHub account, browse to “Account Overview,” and attach the new key, within the “SSH Public Keys” section. To retrieve the value of the key that you just created, return to the Terminal, and type: vim ~/.ssh/id_rsa_COMPANY.pub. Copy the entire string that is displayed, and paste this into the GitHub textarea. Feel free to give it any title you wish.

    Next, because we saved our key with a unique name, we need to tell SSH about it. Within the Terminal, type: ssh-add ~/.ssh/id_rsa_COMPANY. If successful, you’ll see a response of “Identity Added.”

    Step 3 – Create a Config File

    We’ve done the bulk of the workload; but now we need a way to specify when we wish to push to our personal account, and when we should instead push to our company account. To do so, let’s create a config file.

    touch ~/.ssh/config
    vim config
    

    If you’re not comfortable with Vim, feel free to open it within any editor of your choice. Paste in the following snippet.

    #Default GitHub
    Host github.com
      HostName github.com
      User git
      IdentityFile ~/.ssh/id_rsa
    

    This is the default setup for pushing to our personal GitHub account. Notice that we’re able to attach an identity file to the host. Let’s add another one for the company account. Directly below the code above, add:

    Host github-COMPANY
      HostName github.com
      User git
      IdentityFile ~/.ssh/id_rsa_COMPANY
    

    This time, rather than setting the host to github.com, we’ve named it as github-COMPANY. The difference is that we’re now attaching the new identity file that we created previously: id_rsa_COMPANY. Save the page and exit!

    Step 4 – Try it Out

    It’s time to see if our efforts were successful. Create a test directory, initialize git, and create your first commit.

    git init
    git commit -am "first commit'
    

    Login to your company account, create a new repository, give it a name of “Test,” and then return to the Terminal and push your git repo to GitHub.

    git remote add origin git@github-COMPANY:Company/testing.git
    git push origin master
    

    Note that, this time, rather than pushing to git@github.com, we’re using the custom host that we create in the
    config file: git@github-COMPANY.

    Return to GitHub, and you should now see your repository. Remember:

    • When pushing to your personal account, proceed as you always have.
    • For your company account, make sure that you use git!github-COMPANY as the host.

    Be sure to refer to the screencast if you need a more visual overview of the steps above!


  • Permalink for 'Quick Tip: How to Keep the Count with CSS'

    Quick Tip: How to Keep the Count with CSS

    Posted: November 1st, 2011, 6:17pm MDT by Jeffrey Way

    Did you know that, with CSS, you can create a counter? This can be especially useful for instances where the count is purely needed for presentational purposes. I’ll show you how to use counter-increment in this useful quick tip.

    Screencast

    Choose 720p for the best picture. How Does it Work?

    It’s really quite simple. We’re not even talking CSS3 here; the counter-increment property has been around for a while now. It’s just that many of us aren’t familiar with it, or haven’t found a use for it.

    We begin by applying the counter-increment property. Let’s imagine that we have a set of boxes, and each box should display a number that corresponds to the order that the box occurs it its sequence.

    .box {
      counter-increment: boxes;
    }
    

    The counter-increment property can accept either one or two properties. The first is an id that you will later use to reference this specific counter. You may also pass a second parameter that refers to the increment. For example, instead of 1, 2, 3, 4, you could switch to 5, 10, 15, 20 by applying: counter-increment: boxes 5.

    This code will now store a unique number for each element that has a class of box. But of course, we want to get this number on the page. Hopefully, we’ll, at some point in the future, be able to use the content property within standard selectors, but not quite yet. Instead, we’ll use pseudo elements to apply the content.

    .box:after {
      content: counter(boxes);
    }
    

    This will apply a unique number – again, based on the element’s order in the sequence – to the .box element. Should we need to reset this order back to 1 at some point, we could usethe counter-reset: boxes property.

    Why Do This, Again?

    Now, you still might be thinking: “Why would I ever use this?” There’s lots of situations when it might be handy. For example, consider a comments section of a blog. If you wanted to provide
    a number for each comment in the set – possibly slightly transparent – you could use this technique. The number isn’t vital to the markup, and is only used for presentation. In these cases, CSS
    counters will do the trick nicely!


  • Permalink for 'Are TextMate and Coda Yesterday’s Editors?'

    Are TextMate and Coda Yesterday’s Editors?

    Posted: October 26th, 2011, 8:00am MDT by Jeffrey Way

    Based on the title alone, many of you might cry, “blasphemy.” TextMate particularly has been a cornerstone for Mac-based web developers for years and years. However, things change, and, recently, better editors, like Sublime Text 2, have surfaced. With TextMate 2 and Coda 2 on the near horizon, can they compete, or are they too late to the next inning? The editor wars have begun.

    Competition is Good

    Competition is always most beneficial to the consumer.

    Competition is always most beneficial to the consumer. There were the gas wars, then soda wars, and now – in our little world – editor wars.

    Okay, okay, it’s not quite as dramatic as that, but if you don’t think the creators of Coda are keeping a close eye on the beta of TextMate 2 – scheduled for release by Christmas – then you’re surely mistaken. Of course, the same is true vice versa.

    Sublime Text 2, still in beta, has quickly gathered a faithful following, including yours truly. Undoubtedly, the creators of Coda and TextMate have paid attention. After years of waiting, both Coda and TextMate are prepping their respective Version 2 Betas. We’re certainly in for exciting times.

    But the question is: are they too late?

    In Order to Switch Back…

    What would I need in order to switch back to Coda or TextMate?

    I’d love to be blown away by version two of either of these upcoming releases, and, while I think it’s a possibility, I’m still cautious. Sublime Text 2 has been executed so well (while still being in beta); it would be very tough to sway me at this point.

    All of this talk about new code editors, though, has lead me to pause and think: what would I need in order to switch back to Coda or TextMate – both of which I’ve used at different points in my career?

    1 - Multiple Cursors

    This is a requirement for me at this stage. For those unfamiliar with the idea of multiple cursors, it allows you to designate more than one cursor in your document. This is incredibly helpful. Imagine, rather than performing a search and replace to update a word, simply selecting the words, creating the necessary extra cursors, and typing away.

    2 - iCloud?

    Apple’s iCloud works amazingly well. I love downloading an iTunes song on my laptop, and seeing it immediately show up on my phone. What if the same idea could be applied to my local projects and demos?

    • I create a new demo project on my desktop.
    • This then immediately syncs to my other applicable devices.
    • When I open the editor on my laptop at home, it immediately shows up.

    Sure, this can be accomplished with something like Dropbox, but it still requires a bit of effort on my part to organize.

    The winner of the editor wars will provide the most flexibility and simplicity.

    3 - Vi Mode

    It’s not like developers prefer the aesthetics of Vim…

    Many of you laugh at those of us who depend on Vi(m). Huh? I have to type ciw to change this word? Why not just select the text with your mouse?

    Yes, yes, we get it; you prefer the mouse over the keyboard. But the bottom line is: if you put in the necessary time to learn the keybindings, I can promise you that you’ll be significantly faster when browsing and editing your files.

    There needs to be an optional command-esque mode in these editors. Certainly, it should be disabled by default, but give me the option. Think of it this way; if the editor makers themselves don’t add support, a user will create a less-than-ideal plugin. Let’s cut out the middle-man.

    It’s not like developers prefer the uglier Vim; we, too, salivate when looking at screenshots of Espresso 2. But, aesthetics aren’t enough. We need to have the option of continuing to use the shortcuts that have ingrained themselves in our fingers.

    4 - Seamless FTP Support FTP Support

    This is one that Coda got right from the start (Espresso is quite excellent as well). Give us built-in support for browsing and editing files on our servers. Many argue that it’s better to use a thirty party app, like Transmit, for this purpose. They may be right, but it sure is convenient to have that sidebar always available to you. Convenience is key. I’m amazed that more editors don’t support this functionality out of the box.

    When I speak to Coda lovers, this is the first feature they mention.

    5 - Snippet Manager

    Most editors these days offer some form of baked-in snippet manager. While I tend to use third party apps for this purpose, if done right, it makes a lot of sense to store your snippets catalog directly in your editor of choice.

    The problem is that, thus far, it hasn’t been executed well enough. TextMate works well; I can create a snippet, add multiple tab stops, and assign a shortcut quite easily. But, it still requires too much effort on my part. Give me a seamless pop-up panel, where I can create a snippet – based on the currently selected text – and assign a shortcut sequence to it in less than five seconds.

    6 - Crazy-Fast File Switching

    Sublime Text has spoiled me; quickly switching from file to file is lightning fast.

    Perhaps this one is implied, but it should never be disregarded. It’s the core reason why many developers don’t use bloated IDEs, like Aptana. I should click on the app icon, and be coding within seconds. If I need to browse to a different file, let me type a shortcut, and type the name of the file I wish to view. The quicker the better.

    7 - Code Folding

    Code folding is nothing new or special, but it’s absent in some of these editors, or not implemented well enough. I’d like to see smart code folding in place for both versions.

    8 - Terminal Cloud9

    Cloud9, a web-based editor, has a Terminal-like panel built-in, placed at the bottom of the page at all times. While most developers will likely have Terminal open while coding, it’s still something I’d like to see.

    If I need to clone a GitHub repo, let me do so right in the editor: git clone url. If I need to create three files, let me type, touch file1.html file2.thml file3.html, and be done with it.

    It’s a simple idea, but could be a tremendous help: a built-in Terminal-like panel that defaults to the working directory of the current project.

    9 - Preview Window Preview panel in Espresso

    If not built-in, most editors have a plugin that provides support for quickly previewing an HTML page. Espresso does this beautifully. Particularly for web designers, this is a vital feature to have.

    10 - Syntax Highlighting Syntax Highlighting

    Okay, this is a small one; but it’s irritating when you try a new editor, and are provided with only the base syntax highlighter theme. Why? Give me twenty options built-in. I hate wasting time, as I Google for additional themes. This is an easy one, folks.

    11 - Context-Specific Search and Replace

    My golden boy, Sublime Text, offers a nifty way to perform context-specific search and replace. This means that I can select a few paragraphs of text, and then run a search-and-replace command specifically on that selection.

    This way, I can often refrain from resorting to regular expressions to update my documents. It’s a small, but very helpful feature to have.

    12 - Split-Screen Editing Split-Screen Editing

    This is where Vim leads the pack. All on the same screen, I can be editing four different files at once. This is certainly preferred to switching from file to file. Imagine seeing your model, controller, and view file all on the same screen. In the words of Borat, “it’ssa nice!”

    This feature must be baked in for me to switch back.

    13 - Downloads

    We often begin projects by either downloading a framework, or cloning a repository from GitHub. Wouldn’t it be nice if the editor made this as easy as possible – even for those who hate the command line?

    What if, when I create a new project, it gives me the option of pasting in a url.

    • If it’s a link to a .zip file, the editor downloads the file, and unzips its contents into the current directory.
    • If it’s a GitHub link, it clones or downloads the referenced files.

    This is a common gripe, and is specifically why we made Nettuts+ Structurer.

    14 - Auto-Format

    Visual Studio provides the best auto-formatting.

    I’ve yet to find an editor that performs automatic code formatting as well as Visual Studio. Microsoft implemented that feature perfectly. Of the other editors that attempted something similar, I’ve generally found that they fall far short – almost to the point of being unusable.

    15 - Auto-Completion

    If you add too many bells and whistles, you end up with the bloated IDE that many of us try to avoid.

    Here’s the thing: if you add too many bells and whistles, you end up with the bloated IDE that many of us try to avoid. The core appeal of TextMate was that it wasn’t the kitchen sink.

    That said, if they could keep the editor as fast as possible, and still provide a nice auto-completion option, that would be huge. Espresso does this quite well when writing CSS. I’d like to see this across the board. Komodo’s implementation comes to mind.

    16 - Zen Coding Support

    I want to see Zen Coding built into the editor.

    Zen Coding is usually the first plugin I install for a code editor. This is time consuming, and requires me to research exactly how to install it.

    In the same way that Ruby on Rails provides support for the most commonly used tools and preprocessors, a code editor should do the same. I want to see Zen Coding built into the editor. While you’re at it, also provide syntax highlighting for the most popular template languages and preprocessors, like HAML, Slim, Mustache, Sass, and CoffeeScript. Don’t make me hunt these down on GitHub.

    17 - Bookmarks

    Taking another page from the Vim toolkit, bookmarks give us a way to quickly return to a specific line in our project.

    For instance, let’s say that you’re working on a particular view, but have forgotten the name of some variable that was created in your controller. In Vim, you can set a bookmark, switch over to the controller file where the variable was declared, and then instantly return to the exact line you were on in your view with a keyboard shortcut.

    I’d love to see this in the new crop of editors.

    18 - Built-in Compilers Sass

    Sometimes, it’s better to designate specific actions to third party tools and apps. At the same time, though, my decision when choosing a new code editor comes down to convenience. Which editor requires me to perform the least amount of work?

    What if, in my code editor, I could right-click on, say, a Sass file, and choose “compile.” It would then, based on my settings, create the applicable stylesheet. Or, the same thing for a CoffeeScript file.

    This way, I don’t need to bother with the command line if I’m not familiar with it, and I don’t need to use apps that are made specifically to watch and compile Sass and/or CoffeeScript files. It’s important to remember that not everyone is comfortable with the Terminal. As a result, they know nothing about build scripts, and generally stray from using these awesome preprocessors. A “right-click” solution would fix this!

    I’d love to see an editor provide support for the most common preprocessors. Maybe it’s not the job of the code editor, but it sure would provide me with more convenience. Isn’t that the goal?

    19 - Inline Error Checking

    This is a scary one; in my experiences, real-time error checking can drastically slow down an editor – and that’s not an option. Speed takes precendence over everything else.

    That said, if the creators could find a way to provide some level of error checking without sacrificing performance, that would be a huge help.

    20 - Training

    Train your users.

    Sometimes, as consumers, we’re left with the task of sorting through confusing documentation to figure out how to perform common tasks.

    I want to see a variety of screencasts on how to use the editor like a pro. Show me everything from the basics, all the way up to advanced tips and tricks. Visual training is the preference of many, yet it’s so often not provided.

    As the creator of the editor, you know better than anyone about how to use it to its fullest. Train your users.

    21 - The Holy Grail? A Smart Visual Editor

    If one of these editors could produce the pinnacle visual editor, they could change the landscape entirely.

    Wait…wait…put away the guns. I’m not advocating the use of visual editors – at least not yet. Let’s be straight: we’re not against visual editors because we’re code obsessed snobs. We’re against them because they generate terrible markup. Clean code and markup is an art; when you use a visual editor that produces the opposite of art, you should expect a lashing from your peers.

    But, what if they could get it right? Truthfully, I think this isn’t even a possibility for Coda or TextMate 2, but it’s still fun to consider. If one of these editors could produce the pinnacle visual editor, they could change the landscape entirely. Visual Studio has come the closest of everyone, but even they have fallen short. Maybe it will never happen.

    But Most Importantly…

    I want to see features that I haven’t even thought of. Nintendo continues to change the landscape of videogames by offering new ways to experience and interact with their games. I’d like to see the same from the next round of code editors. What will make my life as a developer or designer easier? What have I not thought of yet? That’s what I’m hoping to see most of all from Coda 2 and TextMate 2.


  • Permalink for 'The Magic of WordPress Custom Post Types: New on Premium'

    The Magic of WordPress Custom Post Types: New on Premium

    Posted: October 19th, 2011, 1:14pm MDT by Jeffrey Way

    In this in depth Premium video tutorial, I’ll teach you how to use custom post types, taxonomies, and meta boxes to extend your WordPress application into CMS-like territory.

    Become a Premium member to read this tutorial/screencast, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network.

    You’ll Learn About…
    • What are custom post types, and why would you want to use them?
    • How to take advantage of custom taxonomies to provide additional grouping and filtering functionality
    • How to use custom meta boxes to save and display custom meta information for a specific post type.
    • Implement nonces to provide additional security.
    • New PHP 5.3 features, such as anonymous functions and closures.
    • Plenty more…

    Become a Premium member to read this tutorial/screencast, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network. For more WordPress tutorials every day, be sure to subscribe to our sister-site, WPtuts+!


  • Permalink for 'How to Build an RSS Reader with jQuery Mobile'

    How to Build an RSS Reader with jQuery Mobile

    Posted: October 17th, 2011, 12:00pm MDT by Jeffrey Way

    Twice a month, we revisit some of our readers’ favorite posts from through out the history of Nettuts+. This tutorial was first published in October 2010.

    Today, we’ll dive into jQuery Mobile, which, at the time of this writing, is in a RC1 state. We’ll build a simple Tuts+ RSS reader, using PHP and jQuery Mobile. When we’re finished, you’ll have the ability to add this simple project to your iPhone or Android phone with the click of a button, as well as the skills to build your own custom mobile web apps!

    Step 1: Outline the Project

    It’s always helpful to first outline what you want your project to do/achieve.

    • Display a list of every Tuts+ site, along with its square logo
    • Display the feed for each site, when clicked on
    • Create a basic *article* stylesheet for rendering each posting
    • Create an Apple-touch icon for the users who add the “app” to their phone
    • Use YQL to retrieve the desired RSS feed
    • Implement a basic form of “text file” caching every three hours
    Step 2: Begin

    The next step is to begin creating our project. Go ahead and make a new folder — name it how you wish — and add a new header.php file. *Note that this project uses PHP. If you’re not familiar with this language, feel free to skip the PHP parts! Within this file, we’ll reference jQuery mobile, its stylesheet, and any other assets that we require. If only to stay organized, I’ve placed my header.php file within an includes/ folder.

    <!DOCTYPE html>
    <html>
       <head>
       <meta charset="utf-8">
       <meta [http-equiv="X-UA-Compatible"] content="IE=edge,chrome=1" />
    
       <title> Tuts+ </title> 
    
       <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
       <link rel="apple-touch-icon" href="img/tutsTouchIcon.png" />
    
       <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
       <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
    </head>
    

    There are a handful of things worth noting here.

    1. An HTML5 doctype is required. But you should be using that anyways!
    2. The X-UA-Compatible tag forces IE to use it most current rendering engine
    3. We need to reference jQuery Mobile’s stylesheet. You can use their CDN, and save on bandwidth!
    4. If you want to designate an icon for when users add your webpage to their iPhone (or Android) home screen, add a link tag, with a rel attribute of apple-touch-icon.
    5. We’re referencing the most recent version of jQuery: 1.4.3
    6. Finally, we’re loading the jQuery mobile script file (currently in Alpha 1)
    The Basic Structure

    The jQuery Mobile framework can be activated by applying unique data-* attributes to your code. The basic structure for most sites will look similar to:

    <!-- Let's include the header file that we created above -->
    <?php include('includes/header.php'); ?>
    <body>
     <div data-role="page">
    
       <header data-role="header">
    
       </header>
    
       <div data-role="content">
    
       </div>
    
       <footer data-role="footer">
    
       </footer>
    
     </div>
    
    </body>
    </html>
    

    Add the code above to a new index.php file, within the root of your project.

    We have to tell jQuery about our project. For example, try not to think of each file as a page. Technically, you can create multiple pages at a time, by adding additional wrapping data-role="page" attributes. These are referred to as inner pages.

    Further, the framework has specific settings and stylings in place for the header, main content area, and footer. To inform jQuery Mobile about the locations of these elements, we add the following attributes.

    • data-role="header"
    • data-role="content"
    • data-role="footer"
    No Data Attributes Applied

    No data-role attributes have been applied.

    Data Applied

    Data-role attributes applied.

    Step 3: Listing the Tutorial Sites

    Now that the structure of our index.php page is complete, we can populate each section with our Tuts+ specific mark-up.

    <body>
     	<div>
    	    <header data-role="header">
    	    	<h1> <img src="img/TLogo.png" alt="Tuts+"/> </h1>
    	    </header>
    
    	    <div data-role="content">
    			<ul>
    				<li>
    					<img src="img/ntLogo.jpg" alt="Nettuts" class="ui-li-icon"/>
    					<a href="site.php?siteName=nettuts"> Nettuts+ </a>
    				</li>
    				<li>
    					<img src="img/psdLogo.jpg" alt="Psdtuts" class="ui-li-icon"/>
    					<a href="site.php?siteName=psdtuts"> Psdtuts+ </a>
    				</li>
    				<li>
    					<img src="img/vectorLogo.jpg" alt="Vectortuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=vectortuts"> Vectortuts+ </a>
    				</li>
    				<li>
    					<img src="img/mobileLogo.png" alt="Mobiletuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=mobiletuts"> Mobiletuts+ </a>
    				</li>
    				<li>
    					<img src="img/aeLogo.jpg" alt="Aetuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=aetuts"> Aetuts+ </a>
    				</li>
    				<li>
    					<img src="img/photoLogo.jpg" alt="Phototuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=phototuts"> Phototuts+ </a>
    				</li>
    				<li>
    					<img src="img/cgLogo.jpg" alt="Cgtuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=cgtuts"> Cgtuts+ </a>
    				</li>
    				<li>
    					<img src="img/audioLogo.jpg" alt="Audiotuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=audiotuts"> Audiotuts+ </a>
    				</li>
    				<li>
    					<img src="img/wdLogo.jpg" alt="Webdesigntuts+" class="ui-li-icon"/>
    					<a href="site.php?siteName=webdesigntutsplus"> Webdesigntuts+ </a>
    				</li>
    			</ul>
    	    </div>
    
    	    <footer data-role="footer">
    			<h4> www.tutsplus.com </h4>
    	    </footer>
    
    	</div>
    
    </body>
    </html>
    
    • Header: In this section, we’re simply inserting the Tuts+ graphic, and providing alternate text if images are turned off.
    • Content: In the content area, we need to list all of the tutorial sites, and apply a unique icon next to each heading. We also link to a new page, site.php that will handle the process of retrieving the RSS feed. For convenience, when we link to site.php, we also pass through the name of the selected site, via the querystring: siteName=nettuts.
    • Footer: At the bottom, for now, we’ll simply add a link to Tuts+.

    jQuery Mobile offers a plethora of helpful CSS classes, including ui-li-icon. When applied to an image, it’ll float it to the left, and apply 10px worth of margin-right.

    Our project so far

    At this point, our site should look like the above image.

    Page Transitions

    As jQuery will load local pages asynchronously with AJAX, we can specify any number of cool page transitions. The default is the basic slide-left or slide-right effect that most touch-phone users are aware of. To override the default, use the data-transition attribute on the anchor tag.

    <a href="site.php?siteName=nettuts" data-transition="pop"> Nettuts+ </a>
    
    Available Transitions
    • slide
    • slideup
    • slidedown
    • pop
    • flip
    • fade
    Step 4: ListViews

    Ehh – the image, shown above, still looks like a website. We need to make things a bit more phone-like. The answer is to use the data-role="listview" attribute. Watch what happens when we do nothing more than apply this attribute to the wrapping unordered list.

    Using the listview data-role attribute

    Wow – what an improvement! Even better, we have access to theme-roller, which allows us, with the change of a single letter, to switch color themes.

    <ul data-role="listview" data-theme="a">
    
    Theme A
    <ul data-role="listview" data-theme="b">
    
    Theme B
    <ul data-role="listview" data-theme="e">
    
    Theme E List Dividers

    Now, what if we wanted to divide this list of tutorial sites? In these situations, we can take advantage of data-role="list-divider", which can be applied to the <li> element.

    List Divider

    These, too, can receive lettered theme roller stylings. They can be set within the parent <ul>.

    <ul data-role="listview" data-dividertheme="d">
    
    Divider Theme
    Learn more about list dividers.

    Note that we won’t be using dividers for this particular application.

    Step 5: CSS

    jQuery Mobile takes care of a great deal of the formatting, however, we still, of course, need our own stylesheet for tweaking. For example, looking at the images above, we can see that the tutorial icons need to be pushed up a bit. Additionally, I’d like to use the Tuts+ red for the background color of the heading and footer, rather than the default black.

    Create a new folder, CSS, and add a new stylesheet — I’ll call mine: mobile.css. Within this file, we’ll first fix the icon positioning:

     .ui-li-icon {
       top:  9px;
    }
    

    Next, we’ll create a handful of classes, named after their respective tutorial sites. These classes will contain any specific formatting/colors for the site. For example, Nettuts+ has a darker green color, while MobileTuts+ is yellow.

    .tuts { background: #c24e00; }
    .nettuts { background: #2d6b61; }
    .psdtuts { background: #af1c00; }
    .vectortuts { background: #1e468e; }
    .aetuts { background: #4a3c59; }
    .phototuts { background: #3798aa; }
    .cgtuts { background: #723b4a; }
    .audiotuts { background: #4b7e00; }
    .webdesigntutsplus { background: #0d533f; }
    .mobiletuts { background: #dba600; }
    

    That should be fine for now. The last step for index.php is to apply the .tuts class to the header and footer elements. That way, the header and footer will render the correct background color.

    <header data-role="header" class="tuts">
    ...
    <footer data-role="footer" class="tuts">
    
    Added the Tuts Color Step 6: YQL, PHP, and Caching

    Now, it’s time to step away from the layout, and work on the functionality. Each of the links we created directed to site.php?siteName="siteName". Let’s go ahead and create that file now.

    Even though this is a relatively tiny app, we should still strive to follow best practices. In this case, it means that we should keep as little PHP in our document as possible. Instead, we’ll use site.php as a controller of sorts. This file will handle the initial logic, and will then, at the bottom, load in our HTML template.

    Assigning the Site Name

    In order to retrieve the desired RSS feed, we first need to capture the name of the site that the user clicked on initially. If you’ll refer to a previous step, when we linked to site.php, we also passed the name of the site through the querystring. With PHP, this can easily be retrieved, with $_GET['siteName']. However, what if, for some odd reason, this value doesn’t exist? Maybe site.php was accessed directly?? We should set a default site to compensate for these situations.

    $siteName = empty($_GET['siteName']) ? 'nettuts' : $_GET['siteName'];
    

    If $_GET['siteName'] is empty, we’ll set “nettuts” to the variable, $siteName. Otherwise, it’ll be equal to the name of the respective site.

    Security

    Even though this is a small project, let’s also try to set some security in place. To prevent the user from automatically assigning a potentially dangerous value to the siteName key, let’s ensure that the value is in fact the name of one of our tutorial sites.

    // Prepare array of tutorial sites
    $siteList = array(
       'nettuts',
       'flashtuts',
       'webdesigntutsplus',
       'psdtuts',
       'vectortuts',
       'phototuts',
       'mobiletuts',
       'cgtuts',
       'audiotuts',
       'aetuts'
    );
    
    // If the string isn't a site name, just change to nettuts instead.
    if ( !in_array($siteName, $siteList) ) {
       $siteName = 'nettuts';
    }
    

    The in_array() function allows us to determine if a value — in our case, the value of $siteName — is equal to one of the items in the $siteList array.

    Caching

    Ultimately, we’ll be using the excellent YQL to perform our queries. Think of YQL as an API for APIs. Rather than having to learn twenty different APIs, YQL’s SQL-like syntax allows you to only learn one. However, though YQL does perform a bit of caching on its own, let’s also save the RSS feeds to a text file on our server. That way, we can improve performance a fair bit.

    We begin by creating a new variable, $cache, and making it equal to the location of where the cached file will be stored.

    $cache = dirname(__FILE__) . "/cache/$siteName";
    

    The code above points to the current directory of the file, and then into a cache folder, and, finally, the name of the selected site.

    I’ve decided that this cached file should be updated every three hours. As such, we can run a quick if statement, and determine the last time that the file was updated. If the file does not exist, or the update was longer than three hours ago, we query YQL.

    $cache = dirname(__FILE__) . "/cache/$siteName";
    // Re-cache every three hours
    if( filemtime($cache) 
    

    YQL is ridiculously easy to work with. In our case, we'll use it for a very simple purpose: grab the RSS feed, in JSON form, of the site that was passed through the querystring, via siteName. You can experiment with the various commands by using the YQL console.


    YQL Console

    To query an RSS feed, we using the command: SELECT * FROM feed WHERE url="path/to/rss/feed".

    Building the Path

    For the sake of readability, we'll build up our YQL query in sections.

     // YQL query (SELECT * from feed ... ) // Split for readability
     $path = "http://query.yahooapis.com/v1/public/yql?q=";
     $path .= urlencode("SELECT * FROM feed WHERE url='http://feeds.feedburner.com/$siteName'");
     $path .= "&format=json";
    

    The key is the second part above; when the page loaded, we grabbed the name of the site from the querystring. Now, we only need to insert it into the SELECT query. Luckily, all of the tutorial sites use Feedburner! Make sure that you urlencode the query to replace any special characters.

    Okay, the path is ready; let's use file_get_contents() to grab the feed!

    $feed = file_get_contents($path, true);
    

    Assuming that $feed is now equal to the returned JSON, we can store the results in a text file. However, let's first ensure that data was returned. As long as something is returned from the query, $feed->query->count will be equal to a value greater than zero. If it is, we'll open the cached file, write the data to the file, and finally close it.

    // If something was returned, cache
    if ( is_object($feed) && $feed->query->count ) {
       $cachefile = fopen($cache, 'w');
       fwrite($cachefile, $feed);
       fclose($cachefile);
    }
    

    It seems confusing, but it's really not. The function fopen() accepts two parameters:

    • The file to open: We stored this path in the $cache variable at the top of the page. Note that, if this file doesn't exist, it will create the file for you.
    • Access privileges: Here, we can specify which privileges are available. w stands for "write."

    Next, we open that file, and write the contents of $feed (the returned RSS JSON data) to the file, and close it.

    Using the Cached File

    Above, we first checked whether the cached file was greater than three hours old.

    if( filemtime($cache) 
    

    But what if it wasn't? In that case, we run an else statement, and grab the contents of the text file, rather than using YQL.

    if( filemtime($cache) 
    

    Lastly, we can't do much with the JSON RSS feed until we decode it with PHP.

    // Decode that shizzle
    $feed = json_decode($feed);
    

    And that should do it for our controller! With the logic out of the way, let's include our HTML template.

    // Include the view
    include('views/site.tmpl.php');
    

    Here's our final site.php. Click on the expand icon to view it.

    <?php
    // If "siteName" isn't in the querystring, set the default site name to 'nettuts'
    $siteName = empty($_GET['siteName']) ? 'nettuts' : $_GET['siteName'];
    
    $siteList = array(
       'nettuts',
       'flashtuts',
       'webdesigntutsplus',
       'psdtuts',
       'vectortuts',
       'phototuts',
       'mobiletuts',
       'cgtuts',
       'audiotuts',
       'aetuts'
    );
    
    // For security reasons. If the string isn't a site name, just change to
    // nettuts instead.
    if ( !in_array($siteName, $siteList) ) {
       $siteName = 'nettuts';
    }
    
    $cache = dirname(__FILE__) . "/cache/$siteName";
    // Re-cache every three hours
    if(filemtime($cache) query->count ) {
          $cachefile = fopen($cache, 'wb');
          fwrite($cachefile, $feed);
          fclose($cachefile);
       }
    }
    else
    {
       // We already have local cache. Use that instead.
       $feed = file_get_contents($cache);
    }
    
    // Decode that shizzle
    $feed = json_decode($feed);
    
    // Include the view
    include('views/site.tmpl.php');
    
    Step 7: The Site Template

    At the end of the previous step, we loaded in our template (or view). Go ahead and create that views folder, and site.tmpl.php file. Feel free to name it how you wish. Next, we'll insert our HTML.

    <?php include('includes/header.php'); ?>
    <body> 
    
    <div data-role="page">
    
       <header data-role="header" class="<?php echo $siteName; ?>">
          <h1><?php echo ucwords($siteName).'+'; ?></h1>
       </header>
    
       <div data-role="content">
          <ul data-role="listview" data-theme="c" data-dividertheme="d" data-counttheme="e">
    
          </ul>
       </div>
    
       <footer data-role="footer" class="<?php echo $siteName; ?>">
          <h4> www.tutsplus.com</h4>
       </footer>
    </div>
    
    </body>
    </html>
    
    Points of Interest Above
    • Notice how we follow the same basic layout: header, content area, footer.
    • As this template will be used for every Tuts+ tutorial site, we need to set the title dynamically. Luckily, if you remember, the site name was passed through the querystring, and stored in the $siteName variable (like, "nettuts"). To capitalize the first letter, and apply the signature + after the name, we'll run the variable through ucwords() (uppercases the first letter of each word in the string), and append a "+": <h1><?php echo ucwords($siteName).'+'; ?></h1>
    • We'll soon be displaying the number of comments for each posting next to the title. We can, again, use ThemeRoller to style it, via the data-counttheme="e" attribute.
    Site Template Thus Far Filtering Through the Feed

    At this point, we have access to the $feed object that contains our RSS feed. To dissect this object, you can either print_r($feed), or use the YQL console for a prettier view. We'll use the latter in this case. Check">[http%3A] it out.

    ">[http%3A]
    Dissecting the feed

    To grab the data for each posting, we need to filter through: $feed->query->results->item. PHP makes this a cinch with foreach().

    Within the foreach() statement, we can now access the desired values with $item->title, or $item->comments, which will display the title, and the comment number, respectively. Add the following within the <ul> tags.

    <ul data-role="listview" data-theme="c" data-dividertheme="d" data-counttheme="e">
    <?php
        foreach($feed->query->results->item as $item) { ?>
    
        <li>
          <h2>
             <a href="article.php?siteName=<?php echo $siteName;?>&origLink=<?php echo urlencode($item->guid->content); ?>">
                   <?php echo $item->title; ?>
             </a>
          </h2>
          <span class="ui-li-count"><?php echo $item->comments; ?> </span>
       </li>
    
    <?php  } ?>
    </ul>
    

    In the code above, we build up a list item, containing the title of the posting, the number of comments, and a link to article.php that also contains the site name and the permanent link (to the original article on the Tuts+ site) in the query-string.

    When we view the updated page in the browser, tada!

    Recent article list

    Notice how the comment count is in a yellow bubble, and is floated to the right? That's because we applied the data-counttheme="e" attribute to the wrapping unordered list. How convenient.

    Hmm...I think the text is too large for these long titles. A quick visit to Firebug shows that I can target the h2 tags with a class of .ui-li-heading. Let's return to our stylesheet (mobile.css), and add a new rule:

    .ui-li-heading { font-size: 12px; }
    

    That's better.

    Applying a smaller heading size Step 8: Displaying the Full Posting

    The final step is to build article.php, which will display the entire posting. As with site.php, article.php will serve as our controller, and will query the selected article with YQL, and load the appropriate view.

    <?php
    
    $siteName = $_GET['siteName'];
    $origLink = $_GET['origLink'];
    
    // YQL query (SELECT * from feed ... ) // Split for readability
    $path = "http://query.yahooapis.com/v1/public/yql?q=";
    $path .= urlencode("SELECT * FROM feed WHERE url='http://feeds.feedburner.com/$siteName' AND guid='$origLink'");
    $path .= "&format=json";
    
    $feed = json_decode(file_get_contents($path));
    $feed = $feed->query->results->item;
    
    include('views/article.tmpl.php');
    

    If you've been following along, the code above should look a bit more familiar to you. When we loaded this page, from site.php, we passed through two items, via the query string:

    • Site Name: Contains the name of the currently selected tutorial site
    • Orig Link: A link to the original posting on the tutorial site

    The difference with the YQL query, this time, is that we match the guid (orig link) with the posting that the user clicked on (or pressed). This way, exactly one posting will be returned. Check">[http%3A] out this sample YQL query to gain a better idea of what I mean.

    New YQL query Article Template

    At the bottom of the code above, we loaded the template file for the article page: views/article.tmpl.php. We'll create that file now.

    <?php include('includes/header.php'); ?>
    <body> 
    
    <div data-role="page">
    
       <header data-role="header" class="<?php echo $siteName; ?>">
          <h1> <?php echo ucWords($siteName).'+'; ?> </h1>
       </header>
    
       <div data-role="content">
            <h1> <?php echo $feed->title; ?> </h1>
            <div> <?php echo $feed->description; ?> </div>
       </div>
    
       <footer data-role="footer" class="<?php echo $siteName; ?>">
          <h4> <a href="<?php echo $feed->guid->content;?>"> Read on <?php echo ucWords($siteName); ?>+</a></h4>
       </footer>
    </div>
    
    </body>
    </html>
    

    Ah - so familiar. We've already gone over this template. The only difference is that, this time, because there's only one posting from the YQL query to display, we don't need to bother with a foreach() statement.

    Unstyled Article Page
    Unstyled article page

    At this point, on your own, the next step would be to begin applying your desired styling to the article. I don't see a need to go over it in this tutorial, as it all comes down to personal taste. Here's my super-minimal version.

    Minimally styled article page
    Applying a font-size, line-height, padding, and image formatting. Locked Footers

    One last thing: in the footer section of the article, we link to the original posting on Nettuts+. In its current state, the reader will only see that when they reach the bottom of the article. Let's lock the footer to the bottom of the current view-point at all times. We can use the data-position attribute to achieve this.

       <footer data-role="footer" data-position="fixed">
          <h4> <a href="<?php echo $feed->guid->content;?>"> Read on <?php echo ucWords($siteName); ?>+</a></h4>
       </footer>
    

    That's better!

    We're Done!

    And, with relatively little work, we've successfully built a mobile RSS reader for the Tuts+ sites. It can certainly be expanded to provide additional features, error checking, and performance improvements, but this will hopefully get you started! If you'd like to fork the project and make it better, by all means...do! Thanks for reading, and be sure to refer to the jQuery Mobile documentation for more details. I've no doubt that you'll come across more jQuery mobile tutorials on our sister site, Mobiletuts+.

    Add the Reader to your iPhone Home Screen Add to Home Screen
    View the Demo or Make it Better!


  • Permalink for 'Do You Suffer From the Dunning-Kruger Effect?'

    Do You Suffer From the Dunning-Kruger Effect?

    Posted: October 12th, 2011, 7:00am MDT by Jeffrey Way

    Charles Darwin once noted, “Ignorance more frequently begets confidence than does knowledge.” We all know the modern man to whom Darwin refers: the unemployed “musician” who must inform all new acquaintences that he is, in fact, a musician (multiple times). The XHTML and jQuery “expert,” who uses XHTML as a selling point.

    And if you don’t know this guy, maybe you are him!

    Dunning-Kruger

    It’s referred to as the Dunning-Kruger effect.

    The Dunning–Kruger effect is a cognitive bias in which unskilled people make poor decisions and reach erroneous conclusions, but their incompetence denies them the metacognitive ability to recognize their mistakes. The unskilled therefore suffer from illusory superiority, rating their ability as above average, much higher than it actually is, while the highly skilled underrate their own abilities, suffering from illusory inferiority.

    You don’t even know enough to realize just how little you know.

    I recently mentioned on Twitter that, from my experiences, those who label themselves as experts, more often than not… aren’t. This isn’t surprising; it stands to reason – to phrase it casually – that those who have the goods…don’t flaunt the goods! Alternatively, if one’s expertise is persistently revealed to you, by said expert, perhaps something is a few clicks off!

    A guitar teacher of mine in college, once – rightly so – informed me: “You don’t even know enough to realize just how little you know.”

    Little did my teacher know that this comment would stick with me for a long time. The irony, of course, is, despite the fact that years and years have passed since my conversation with him, his note still applies.

    Whether the craft be music or web development, I’m not even close to an expert. Or, as Willy Brown might say, I’m not even the beginnings of a pimple on the late great Robert Johnson’s ass.

    “Actual competence may weaken self-confidence, as competent individuals may falsely assume that others have an equivalent understanding. As Kruger and Dunning conclude, “the miscalibration of the incompetent stems from an error about the self, whereas the miscalibration of the highly competent stems from an error about others.”

    How to Detect a Self-Proclaimed Expert

    According to Wikipedia, for a given skill, self-proclaimed experts will:

    • tend to overestimate their own level of skill
    • fail to recognize genuine skill in others
    • fail to recognize the extremity of their inadequacy
    • recognize and acknowledge their own previous lack of skill, if they can be trained to substantially improve.

    Those who genuinely know their stuff are considerably modest, when compared to those who have a fraction of their experience and knowledge.

    Maybe the easiest way to detect a real expert is via that very word: “expert.” Is it inaccurate for me to argue that true experts rarely refer to themselves as such, if ever? There’s that idea again: “the more you know; the more you realize how little you know.”

    Everything’s relative, of course, but I’ve found that those who genuinely know their stuff are considerably modest, when compared to those who have a fraction of their experience and knowledge. Perhaps this is simple human nature. Blissful ignorance and dreams are many times preferable to actual work. It’s easier to brag about your next million dollar web application, than to actually create it. It’s more impressive to use the terms “gig” and “contract,” when you really mean, “freebie website for my sister.”

    So the question remains: why do some represent expertise, while others seemingly avoid the term? I suppose I can’t speak to the former, though I can provide some personal notes on the latter.

    • First and foremost, I know in my heart that I have a long way to go before I can even fathom embracing that label – if ever.
    • The term, “expert” is a vague one, and is entirely relative. Sure, to a high school student, maybe we are experts. To my personal web development heroes, I feel like a hack. I’m sure the chain continues indefinitely. This is precisely why it’s important to refrain from using these sorts of labels in most cases.
    • Particularly in our field, no one is an expert. The industry is too young, and advances at an alarming rate. There’s always new skills to acquire. I’d argue that those who understand this truth also understand that terms like “expert” are inappropriate.
    • On a more casual and social level, you come across as a jerk when you self-diagnose yourself this way. This is similar to continuously retweeting compliments. Let your work/code do the talking, and, if you genuinely deserve the label, others will be more than happy to assign it to you. This is the correct way to achieve “expert” status. It is given…not proclaimed.
    Is It Ever Okay to Call Yourself an Expert?

    Is it in poor taste to designate yourself as an expert? Ultimately, it’s just a word; do what you wish. I’m admittedly being a bit pedantic here.

    Christian Heilmann argues:

    “Sometimes, you need to call yourself an expert to reach people who are badly in need of information.”

    That’s certainly a valid case, and is particularly applicable when considering events like conferences and workshops. When you host a workshop, regardless of whether you label yourself as an expert, you assume that role. When it comes to spreading education, Christian is right: sometimes you must use these terms to attract those in need. And in these teacher-student relationships, you are the expert. No harm done.

    We also must consider simple marketing or SEO. To John Doe, who needs a website for his new business, it’s important to remind him that we are the “experts.” As more and more tools, which allow regular folks to create websites, are released, they should be made aware that others have dedicated their lives to learning this craft. Don’t risk the livelihood of your business, all for the sake of saving X dollars on the website. You are the expert. John Doe must know this. To the Layman, sure, abuse the term!

    However, among your peers, you might think twice before labeling yourself in this way.

    Arrogance is not inspiring.

    This is not to say that you shouldn’t be confident in your worth and abilities. Never devalue your worth to an employer or client. That said, though, unless you are one of the few truly exceptional veterans in our industry, stop patting yourself on the head, and get back to doing what we all must do in our free-time: learning. Whether you’re an industry veteran or a college student, we all share one commonality: we spend as much free time as possible desperately trying to remain relevant in this ever-expanding industry.

    Conclusion

    As a reader of Nettuts+, I think it’s safe to assume that, like me, you’re considerably aware of the skills you don’t yet have. Hopefully, Nettuts+ can help with that! Until next time, I’ll leave you with this quote:

    “One of the painful things about our time is that those who feel certainty are stupid, and those with any imagination and understanding are filled with doubt and indecision.” – Bertrand Russell


  • Permalink for 'The Intro to Rails Screencast I Wish I Had'

    The Intro to Rails Screencast I Wish I Had

    Posted: October 10th, 2011, 4:20pm MDT by Jeffrey Way

    Isn’t it funny how most “introduction to Ruby on Rails” screencasts are overly simplistic, and rely on generators like scaffolding? The teacher typically follows up the tutorial by stating that most Rails developer don’t use scaffolding generators. Well that’s not much help then! I’d like to give you the tutorial I wish I had. Along the way, we’ll also rely heavily on test-driven development to build a simple app.

    Choose HD for the clearest picture. Covered in this Screencast…
    • Create models and generators
    • Use test-driven development to plan and test an application’s features
    • Work with ActiveRecord
    • Autotest with Guard
    • Use Rspec and Capybara to simulate the user.
    • Create partials
    • Take advantage of Flash notices
    • …and plenty more
    Conclusion

    If you watched the entire screencast, I hope you enjoyed it! There’s certainly much more to cover, but we crammed a great deal into thirty minutes or so! What other tricks and techniques have you picked up, if you’re just digging into Rails?


  • Permalink for 'Quick Tip – jQuery Newbs: Stop Jumping in the Pool'

    Quick Tip – jQuery Newbs: Stop Jumping in the Pool

    Posted: October 7th, 2011, 11:02am MDT by Jeffrey Way

    As editor of Nettuts+, I get to review a lot of code from tutorial submissions. Despite the fact that jQuery has been available for years now, there is still one frequent mistake that I see more than anything else.

    Example #1

    Consider the following bit of code:

    $('.nav a').click(function() {
      $(this).hide();
      $(this).css('color', 'red');
      $(this).show();
    
      alert('something else');
    
      $(this).hide();
    
      return false;
    });
    

    The code above is overly complicated for a variety of reasons. Don’t worry over what the code actually does (it’s gibberish). Instead, I want you to look at all of those references to $(this).

    Think of the DOM as a pool.

    Think of the DOM as a pool. Remember when you were a kid, and would dive into the pool for coins, while your parents acted like they were watching? That will be our real-world comparision.

    Every time you use $('.someClass'), jQuery jumps into the pool (DOM), and searches for that coin (or nodes). So, when you reference it multiple times within a function, that’s a lot of diving. Or, to cut the real-world comparison, it’s wasteful and unncessary. Why call upon jQuery if you don’t require it? You should perform what we call “caching.”

    $('.nav a').click(function(e) {
       var anchor = $(this);
    
       anchor
          .hide()
         .css('color', 'red')
         .show();
    
       alert('something else');
    
       anchor.hide();
    
       e.preventDefault();
    
    });
    

    This is much cleaner. While modern browser engines are incredibly fast these days, and will make up for your poor coding as best as possible, you should still strive to write efficient code, and keep from wasting all that energy jumping in the pool. Now, technically, if you pass jQuery a DOM node, like this, it doesn’t re-query the DOM. It simply returns a jQuery object.

    Just because the performance difference between the two will honestly be negligible, we write clean code for ourselves.

    Example 2

    Let’s consider a slightly more complicated example: tabs.

    $('.tabs li').css('position', 'relative');
    
    $('.tabs li').click(function() {
       $('.tabs li').removeClass('active');
       $(this).addClass('active');
       $(this).load('someHref', function() {} ); // example
       $(this).css('top', '1px');
    });
    

    This code is all over the place. It’s ugly, and inefficient. Fix number one is to get rid of all that CSS. You’d only place styling in your JavaScript if the values were created dynamically. For example, if you need to calculate the precise location an element should be on the screen, you could use .css('left', calculatedValue). In this case, it can all be exported to an external stylesheet. That leaves us with:

    $('.tabs li').click(function() {
       $('.tabs li').removeClass('active');
       $(this).load('someHref', function() {} ); // example
       $(this).addClass('active');
    });
    

    Next, again, why do we keep querying the DOM for .tabs li and $(this)? Stop jumping in the pool. Let’s “cache” the location of .tabs li.

    var tabs = $('.tabs li');
    
    tabs.click(function() {
       tabs.removeClass('active');
       $(this).load('someHref', function() {} ); // example
       $(this).addClass('active');
    });
    

    Better, but we’re still calling $(this) twice, which isn’t a huge deal. But, from my experiences, if you don’t nip it in the bud early, this number quickly increases.

    var tabs = $('.tabs li');
    
    tabs.click(function() {
       var tab = $(this);
       tabs.removeClass('active');
       tab.addClass('active')
         .load('someHref', function() {} ); // example
    });
    
    Filtering

    Another (slightly less optimized) option would be to use filtering.

    var tabs = $('.tabs li');
    
    tabs.click(function() {
       tabs.removeClass('active')
           .filter(this)
           .addClass('active')
           .load('someHref', function() {} ); // example
    });
    

    The difference in this case, is that, rather than referencing $(this), we’re using the filter() method to reduce the collection of list items down to only the one that was clicked.

    What You Should Take Away

    Yes, the world will not end if you reference $('.tabs) several times within a function. JavaScript engines are super fast these days. If you were to test the performance of doing so thousands of times, the difference in execution might be a couple hundred milliseconds. But still, the question remains: why would you?

    Sometimes, when we use massive abstractions like jQuery, it’s easy forget that $('.tabs') is an actual function that runs a good bit of code. It should also be noted that these concepts apply to JavaScript in general – not just jQuery.

    Use the caching techniques described above to write cleaner code…for yourself.


  • Permalink for 'How to Deploy your First Rails App: New on Premium'

    How to Deploy your First Rails App: New on Premium

    Posted: September 30th, 2011, 12:41pm MDT by Jeffrey Way

    In this Premium video tutorial, we’ll teach you how to deploy your first Rails web application with Heroku. Particularly if you’re somewhat new to Rails, you may find that you’re met with a long string of errors when pushing your app and database to their servers. Don’t worry, though; this screencast will take you through the entire process from scratch.

    Become a Premium member to watch this video, as well as hundreds of other advanced tutorials and screencasts from the Tuts+ network.

    You’ll Learn How To…
    • Work with models and controllers
    • Adjust routes
    • Source control with Git
    • Install and work with Heroku
    • Convert a Sqlite3 database to PostgreSQL
    • Debugging Heroku errors


  • Permalink for 'Build Ajax Data Grids with CodeIgniter and jQuery'

    Build Ajax Data Grids with CodeIgniter and jQuery

    Posted: September 22nd, 2011, 12:47pm MDT by Jeffrey Way

    In this lesson, we will create a CodeIgniter library that allows us to generate data grids automatically for managing any database table. I’ll explain each step required to create this class; so you’ll likely learn some new OOP techniques/concepts in the process!

    As a bonus, we’ll proceed to write some jQuery code that will enable a user to update the data grid’s content without having to wait for a page refresh.

    Please Note…

    This tutorial assumes that you have a modest understanding of the CodeIgniter and jQuery frameworks.

    What is a Data Grid?

    A datagrid is a table that displays the contents of a database or table along with sorting controls.

    A datagrid is a table that displays the contents of a database or table along with sorting controls. In this tutorial, we will be tasked with providing this functionality, but also saving the user from waiting for the page to refresh each time an operation is performed. Thanks to jQuery, this will be a fairly simple task!

    What about the users who don’t have Javascript enabled? Don’t worry, we’ll compensate for them as well!

    Step 1: Build a Data Grid Generator Class

    We want to build a tool that will enable us to create datagrids dynamically for any database table that we have. This means the code is not tied up to any specific table structure, and, thus, is independent on the data itself. All the coder (the developer who uses our class) must know is the name of the table to be transformed into a grid and the primary key for that table. Here is the preface of the class that we will be developing for the most part of this tutorial:

    <?php
    class Datagrid{
    	private $hide_pk_col = true;
    	private $hide_cols = array();
    	private $tbl_name = '';
    	private $pk_col	= '';
    	private $headings = array();
    	private $tbl_fields = array();
    }
    ?>
    

    The Datagrid Class could well be added to the application/library folder, but we are going to add it as a helper to the CodeIgniter framework. Why? Because loading libraries doesn’t allow us to pass arguments to the class’ constructor, thus loading it as a helper will solve the problem. This point will make more sense for you when we have finished writing the constructor.

    The Class’ Constructor Method
    public function __construct($tbl_name, $pk_col = 'id'){
    	$this->CI =& get_instance();
    	$this->CI->load->database();
    	$this->tbl_fields = $this->CI->db->list_fields($tbl_name);
    	if(!in_array($pk_col,$this->tbl_fields)){
    		throw new Exception("Primary key column '$pk_col' not found in table '$tbl_name'");
    	}
    	$this->tbl_name = $tbl_name;
    	$this->pk_col = $pk_col;
    	$this->CI->load->library('table');
    
    }
    

    We have much going on already; but don’t worry, as I’ll explain everything for you in the next paragraph.

    The constructor takes two arguments: the first one being the name of the table in your database that you wish to display as a datagrid to the user; the second param is the name of the column serving as the primary key for that table (more on that later). Inside the constructor’s body, we instantiate the CodeIgniter Object, the Database Object and the HTML Table class/library. All of these will be needed throughout a Datagrid object’s lifetime and are already built into the CI framework. Notice that we also check if the primary key really exists in the given table, and, in case it does not, we throw an exception reporting the error. Now the $this->tbl_fields member variable will be available for later use, so we don’t have to fetch the database again.

    “We can use the command, $CI->db->list_fields($tbl_name) to fetch the names of all fields that a table has. However, for better performance, I recommend caching the results.”

    Method for Customizing Table Headings
    public function setHeadings(array $headings){
    	$this->headings = array_merge($this->headings, $headings);
    }
    

    This permits you to customize the headings of your data grid table – that is, with it, you can overwrite the original column names for certain table fields. It takes an associative array, like this: regdate => “Registration Date”. Instead of just the technical “Regdate” as the column heading for that type of data, we have a more human-readable title in its place. The code responsible for applying the headings will be revealed shortly.

    Method for Ignoring/Hiding Table Fields
    public function ignoreFields(array $fields){
    	foreach($fields as $f){
    		if($f!=$this->pk_col)
    			$this->hide_cols[] = $f;
    	}
    }
    

    ignoreFields receives an array containing the fields to be ignored when fetching data from the database. This is useful when we have tables with lots of fields, but we only want to hide a couple of them. This method is smart enough to track an attempt to ignore the primary key field and then skip that. This is so because the primary key cannot be ignored for technical reasons (you will see why shortly). Still, if you want to hide the primary key column from appearing in the UI, you can use the hidePkCol method:

    public function hidePkCol($bool){
    	$this->hide_pk_col = (bool)$bool;
    }
    

    This method receives a boolean value to indicate if we want to hide the primary key column so it won’t show up in the data grid. Sometimes, it’s an ugly idea to display the pkey data, which is usually a numerical code without any meaning to the user.

    Next instance method:

    private function _selectFields(){
    	foreach($this->tbl_fields as $field){
    		if(!in_array($field,$this->hide_cols)){
    			$this->CI->db->select($field);
    			// hide pk column heading?
    			if($field==$this->pk_col && $this->hide_pk_col) continue;
    				$headings[]= isset($this->headings[$field]) ? $this->headings[$field] : ucfirst($field);
    		}
    	}
    	if(!empty($headings)){
    		// prepend a checkbox for toggling
    		array_unshift($headings,"<input type='checkbox' class='check_toggler'>");
    		$this->CI->table->set_heading($headings);
    	}
    
    }
    

    Here we have a helper method; that’s why it has the “private” modifier and is prefixed with an underline character (code convention). It will be used by the generate() method – explained shortly – in order to have the appropriate table fields selected and also the appropriate headings set to the table (generator) object. Notice the following line:

    $headings[]= isset($this->headings[$field]) ? $this->headings[$field] : ucfirst($field);
    

    This is where we apply the customized headers or resort to the default ones if none is given. If the pk column is supposed to be hidden from display, then it’s heading will be skipped. Also notice the following line:

    array_unshift($headings,"<input type='checkbox' class='dg_check_toggler'>");
    

    The above command instructs the program to prepend a “Master” checkbox as the first heading of the table. That checkbox is different from other checkboxes in the grid in that it allows a user to check or uncheck all checkboxes in just one go. This toggling functionality will be implemented in a few moments with a simple jQuery code snippet.

    Method to Generate/Render the Datagrid

    Now comes the thing that does the real work for us:

    public function generate(){
    	$this->_selectFields();
    	$rows = $this->CI->db
    			->from($this->tbl_name)
    			->get()
    			->result_array();
    	foreach($rows as &$row){
    		$id = $row[$this->pk_col];
    
    		// prepend a checkbox to enable selection of items/rows
    		array_unshift($row, "<input class='dg_check_item' type='checkbox' name='dg_item[]' value='$id' />");
    
    		// hide pk column cell?
    		if($this->hide_pk_col){
    			unset($row[$this->pk_col]);
    		}
    	}
    
    	return $this->CI->table->generate($rows);
    }
    

    The generate method, as its name suggests, is responsible for generating the data grid itself. You should call this method only after you have configured the object according to your needs. The first thing it does is call the $this->_selectFields() method to perform the actions we explained earlier. Now it has to fetch all rows from the database and then loop through them, adding checkboxes to the beginning of each row:

    // prepend a checkbox to enable selection of items/rows
    array_unshift($row, "<input class='dg_check_item' type='checkbox' name='dg_item[]' value='$id' />");
    

    Inside the foreach loop on the generate method, if the $this->hide_pk_col flag is set to true, then we must unset the primary key entry in the $row array so it won’t show up as a column when the $this->CI->table object processes all rows and generates the final html output. At this point, it is okay to remove the primary key, if necessary, because we no longer need that information. A

    But what does the user do with the selected/checked rows? To answer this, I have prepared a few more methods. The first one enables us to create “action buttons” without having to know any technical details about how the grid system works internally:

    Method for Adding Buttons to a Data Grid Form
    public static function createButton($action_name, $label){
    	return "<input type='submit' class='$action_name' name='dg_action[$action_name]' value='$label' />";
    }
    

    Simply pass the name of the action as the first argument and a second argument to indicate the label for the generated button. A class attribute is automatically generated for that button so we can play around with it more easily when we are working with it in our JavaScript. But, how do we know if a certain action button has been pressed by the user? The answer can be found in the next method:

    public static function getPostAction(){
    // get name of submitted action (if any)
    	if(isset($_POST['dg_action'])){
    		return key($_POST['dg_action']);
    	}
    }
    

    Yep! Another static method that helps us when we are dealing with forms. If any data grid has been submitted, this method will return the name of the action (or “operation”) associated with that submit event. In addition, another handy tool for processing our datagrid forms is…

    public static function getPostItems(){
    	if(!empty($_POST['dg_item'])){
    		return $_POST['dg_item'];
    	}
    	return array();
    }
    

    … which returns an array containing the selected ids so you can track which rows have been selected on the grid and then perform some action with them. As an example of what can be done with a selection of row ids, I have prepared another method – this one being an instance method, and not a static one, because it makes use of the object’s instance resources in order to do its business:

    public function deletePostSelection(){
    // remove selected items from the db
    	if(!empty($_POST['dg_item']))
    		return $this->CI->db
    			->from($this->tbl_name)
    			->where_in($this->pk_col,$_POST['dg_item'])
    			->delete();
    }
    

    If at least one checkbox was checked, the deletePostSelection() method will generate and execute an SQL statement like the following (suppose $tbl_name='my_table' and $pk_col='id'):

    DELETE FROM my_table WHERE id IN (1,5,7,3,etc...)
    

    …which will effectively remove the selected rows from the persistent layer. There could be more operations you could add to a data grid, but that will depend on the specifics of your project. As a tip, you could extend this class to, say, InboxDatagrid, so, beyond the deletePostSelection method, it could include extra operations, such as moveSelectedMessagesTo($place), etc…

    Putting everything together

    Now, if you have followed this tutorial step by step, you should have ended up with something similar to the following:

    class Datagrid{
    
    	private $hide_pk_col = true;
    	private $hide_cols = array();
    	private $tbl_name = '';
    	private $pk_col	= '';
    	private $headings = array();
    	private $tbl_fields = array();
    
    	function __construct($tbl_name, $pk_col = 'id'){
    		$this->CI =& get_instance();
    		$this->CI->load->database();
    		$this->tbl_fields = $this->CI->db->list_fields($tbl_name);
    		if(!in_array($pk_col,$this->tbl_fields)){
    			throw new Exception("Primary key column '$pk_col' not found in table '$tbl_name'");
    		}
    		$this->tbl_name = $tbl_name;
    		$this->pk_col = $pk_col;
    		$this->CI->load->library('table');
    
    	}
    
    	public function setHeadings(array $headings){
    		$this->headings = array_merge($this->headings, $headings);
    	}
    
    	public function hidePkCol($bool){
    		$this->hide_pk_col = (bool)$bool;
    	}
    
    	public function ignoreFields(array $fields){
    		foreach($fields as $f){
    			if($f!=$this->pk_col)
    				$this->hide_cols[] = $f;
    		}
    	}
    
    	private function _selectFields(){
    		foreach($this->tbl_fields as $field){
    			if(!in_array($field,$this->hide_cols)){
    				$this->CI->db->select($field);
    				// hide pk column heading?
    				if($field==$this->pk_col && $this->hide_pk_col) continue;
    				$headings[]= isset($this->headings[$field]) ? $this->headings[$field] : ucfirst($field);
    			}
    		}
    		if(!empty($headings)){
    			// prepend a checkbox for toggling
    			array_unshift($headings,"<input type='checkbox' class='dg_check_toggler'>");
    			$this->CI->table->set_heading($headings);
    		}
    
    	}
    
    	public function generate(){
    		$this->_selectFields();
    		$rows = $this->CI->db
    				->from($this->tbl_name)
    				->get()
    				->result_array();
    		foreach($rows as &$row){
    			$id = $row[$this->pk_col];
    
    			// prepend a checkbox to enable selection of items
    			array_unshift($row, "<input class='dg_check_item' type='checkbox' name='dg_item[]' value='$id' />");
    
    			// hide pk column?
    			if($this->hide_pk_col){
    				unset($row[$this->pk_col]);
    			}
    		}
    
    		return $this->CI->table->generate($rows);
    	}
    
    	public static function createButton($action_name, $label){
    		return "<input type='submit' class='$action_name' name='dg_action[$action_name]' value='$label' />";
    	}
    
    	public static function getPostAction(){
    	// get name of submitted action (if any)
    		if(isset($_POST['dg_action'])){
    			return key($_POST['dg_action']);
    		}
    	}
    
    	public static function getPostItems(){
    		if(!empty($_POST['dg_item'])){
    			return $_POST['dg_item'];
    		}
    		return array();
    	}
    
    	public function deletePostSelection(){
    	// remove selected items from the db
    		if(!empty($_POST['dg_item']))
    			return $this->CI->db
    				->from($this->tbl_name)
    				->where_in($this->pk_col,$_POST['dg_item'])
    				->delete();
    	}
    
    }
    

    Notice: Don’t forget to save this file as datagrid_helper.php, and place it in “application/helper/”

    Step 2: Testing the Datagrid Helper Class with a CodeIgniter Controller

    We’ll now create a simple test controller and load the Datagrid class as a helper in its constructor. But before that, we should define a dummy database table and populate it with some sample data.

    Execute the following SQL to create the database and the user table:

    CREATE DATABASE `dg_test`;
    CREATE TABLE `users` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `username` varchar(80) NOT NULL,
      `password` varchar(32) NOT NULL,
      `email` varchar(255) NOT NULL,
      UNIQUE KEY `id` (`id`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;
    

    Next, let’s add some users to it:

    INSERT INTO `users` (`id`, `username`, `password`, `email`) VALUES
    (1, 'david', '12345', 'david@domain.com'),
    (2, 'maria', '464y3y', 'maria@domain.com'),
    (3, 'alejandro', 'a42352fawet', 'alejandro@domain.com'),
    (4, 'emma', 'f22a3455b2', 'emma@domain.com');
    

    Now, save the following code as “test.php,” and add it to the “application/controllers” folder:

    <?php
    class Test extends CI_Controller{
    
    	function __construct(){
    		parent::__construct();
    		$this->load->helper(array('datagrid','url'));
    		$this->Datagrid = new Datagrid('users','id');
    	}
    
    	function index(){
    		$this->load->helper('form');
    		$this->load->library('session');
    
    		$this->Datagrid->hidePkCol(true);
    		$this->Datagrid->setHeadings(array('email'=>'E-mail'));
    		$this->Datagrid->ignoreFields(array('password'));
    
    		if($error = $this->session->flashdata('form_error')){
    			echo "<font color=red>$error</font>";
    		}
    		echo form_open('test/proc');
    		echo $this->Datagrid->generate();
    		echo Datagrid::createButton('delete','Delete');
    		echo form_close();
    	}
    
    	function proc($request_type = ''){
    		$this->load->helper('url');
    		if($action = Datagrid::getPostAction()){
    			$error = "";
    			switch($action){
    				case 'delete' :
    					if(!$this->Datagrid->deletePostSelection()){
    						$error = 'Items could not be deleted';
    					}
    				break;
    			}
    			if($request_type!='ajax'){
    				$this->load->library('session');
    				$this->session->set_flashdata('form_error',$error);
    				redirect('test/index');
    			} else {
    				echo json_encode(array('error' => $error));
    			}
    		} else {
    			die("Bad Request");
    		}
    	}
    
    }
    ?>
    

    An instance of this class is created and passed as a reference to the $this->Datagrid member. Notice that we will be fetching data from a table called “users” whose primary key is the “id” column; then, on the index method we take the following steps: configure the Datagrid object, render it inside a form with a delete button added to it and see if everything works as expected:

    Question: What happens when the form is sent?

    Answer: The “Test::proc()” method takes care of processing the form and choosing the right operation to apply against the ids that were selected by the form’s sender. It also takes care of AJAX requests, so it will echo a JSON object back to the client. This AJAX-aware feature will come in handy when jQuery comes into action, which is right now!

    “It’s always a smart idea to create web applications which compensates for when JavaScript/AJAX is unavailable. This way, some users will have a richer and faster experience, while those without JavaScript enabled will still be able to use the application normally.”

    Step 3: Implementing Ajax (jQuery to the Rescue!)

    When the user clicks the button (or any other action button), we would like, perhaps, to prevent the page from reloading and having to generate everything again; this could make the user of our application fall asleep! Circumventing this problem will not be a difficult task if we stick to the jQuery library. Since this is not a “beginners” tutorial, I will not go through all the details related to how to get the library, how to include it on the page, etc. You’re expected to know these steps on your own.

    Create a folder, named “js“, add the jQuery library within, and create a view file, named users.php. Open this new file, and add:

    <html>
    <head>
    	<title>Users Management</title>
    	<script src="<?php echo base_url(); ?>js/jquery-1.6.3.min.js"></script>
    	<script src="<?php echo base_url(); ?>js/datagrid.js"></script>
    </head>
    <body>
    <?php
    		$this->Datagrid->hidePkCol(true);
    		if($error = $this->session->flashdata('form_error')){
    			echo "<font color=red>$error</font>";
    		}
    		echo form_open('test/proc',array('class'=>'dg_form'));
    		echo $this->Datagrid->generate();
    		echo Datagrid::createButton('delete','Delete');
    		echo form_close();
    ?>
    </body>
    </html>
    

    Did you realize that we have moved the code away from Test::index and into the new view script? This means we must change the Test::index() method accordingly:

    function index(){
    	$this->load->helper('form');
    	$this->load->library('session');
    	$this->load->view('users');
    }
    

    That’s better. If you want to add some styling to the grid, you could use the following CSS (or make a better layout on your own):

    	.dg_form table{
    		border:1px solid silver;
    	}
    
    	.dg_form th{
    		background-color:gray;
    		font-family:"Courier New", Courier, mono;
    		font-size:12px;
    	}
    
    	.dg_form td{
    		background-color:gainsboro;
    		font-size:12px;
    	}
    
    	.dg_form input[type=submit]{
    		margin-top:2px;
    	}
    

    Now, please, create a “datagrid.js” file, put it on the “js” directory, and start with this code:

    $(function(){
    	// cool stuff here...
    })
    

    Inside this closure, we will write code that will be tasked with controlling certain submit events once the page has completely loaded. The first thing we need to do is track when a user clicks a submit button on the data grid form, and then send that data to be processed on the server.

     	$('.dg_form :submit').click(function(e){
    		e.preventDefault();
    		var $form = $(this).parents('form');
    		var action_name = $(this).attr('class').replace("dg_action_","");
    		var action_control = $('<input type="hidden" name="dg_action['+action_name+']" value=1 />');
    
    		$form.append(action_control);
    
    		var post_data = $form.serialize();
    		action_control.remove();
    
    		var script = $form.attr('action')+'/ajax';
    		$.post(script, post_data, function(resp){
    			if(resp.error){
    				alert(resp.error);
    			} else {
    				switch(action_name){
    					case 'delete' :
    						// remove deleted rows from the grid
    						$form.find('.dg_check_item:checked').parents('tr').remove();
    					break;
    					case 'anotherAction' :
    						// do something else...
    					break;
    				}
    			}
    		}, 'json')
    	})
    

    Alternatively, we could have started with something like: $('.dg_form').submit(function(e){...}). However, since I want to track which button has been pressed and extract the name of the chosen action based on it, I prefer binding an event handler to the submit button itself and then go my way up the hierarchy of nodes to find the form that the pressed button belongs to:

    // finds the form
    var $form = $(this).parents('form');
    // extracts the name of the action
    var action_name = $(this).attr('class').replace("dg_action_","");
    

    Next, we add a hidden input element inside the form element to indicate which action is being sent:

    // create the hidden input
    var action_control = $('<input type="hidden" name="dg_action['+action_name+']" value=1 />');
    // add to the form
    $form.append(action_control);
    

    This is necessary because function doesn’t consider the submit button to be a valid form entry. So we must have that hack in place when serializing the form data.

    action_control.remove();
    

    “Don’t forget: the function ignores the submit button, dismissing it as just another piece of markup junk!”

    Sending Form Data to the Server

    Next, we proceed to get the action attribute from the form element and append the string “/ajax” to that url, so the method will know that this is, in fact, an AJAX request. Following that, we use the jQuery.post function to send the data to be processed by the appropriate controller, server-side, and then intercept the response event with a registered callback/closure:

    ...
    	var script = $form.attr('action')+'/ajax';
    	$.post(script, post_data, function(resp){
    		if(resp.error){
    			alert(resp.error);
    		} else {
    			switch(action_name){
    				case 'delete' :
    					// remove deleted rows from the grid
    					$form.find('.dg_check_item:checked').parents('tr').remove();
    				break;
    				case 'anotherAction' :
    					// do something else...
    				break;
    			}
    		}
    	},'json')
    

    Notice that we are asking the response to be encoded as “json” since we are passing that string as the fourth argument of the $.post function. The contents of the callback dealing with the server response should be rather simple to grasp; it determines if there is an error, and, if so, alerts it. Otherwise, it will indicate that the action was successfully processed (in this case, if it is a “” action, we remove the rows related to the ids that were selected by the user).

    Step 4: Check All or Nothing!

    The only thing that is missing now is the toggle functionality that I promised earlier. We must register a callback function for when the “Master” checkbox – which has a class attribute set to “dg_check_toggler” – is clicked. Add the following code snippet after the previous one:

    	$('.dg_check_toggler').click(function(){
    		var checkboxes = $(this).parents('table').find('.dg_check_item');
    		if($(this).is(':checked')){
    			checkboxes.attr('checked','true');
    		} else {
    			checkboxes.removeAttr('checked');
    		}
    	})
    

    When the “toggler” checkbox is clicked, if it goes to a “checked” state, then all rows from the pertaining data grid will be checked simultaneously; otherwise everything will be unchecked.

    Final Thoughts

    We haven’t reached the tip of the iceberg when it comes to data grids for more complex content management systems. Other features which might prove to be useful are:

    • Sorting the data grid by column names
    • Pagination links for browsing the data grid
    • Edit/Modify links for updating a single row’s data
    • Search mechanism to filter results

    Thanks for reading. If you’d like a follow-up tutorial, let me know in the comments!


  • Permalink for 'Is Conference Pricing Out of Control?'

    Is Conference Pricing Out of Control?

    Posted: September 13th, 2011, 7:00am MDT by Jeffrey Way

    You’ve surely experienced the letdown of registering for a conference, only to find that it costs $1,000 (or more) to attend (not including travel expenses). Isn’t that a bit extreme for two days worth of training? Then again, is that the only way the conference organizers can cover the high cost of planning such an event? Let’s see…

    We’ll put the economics of organizing such an event to the side for the time being, and instead focus on the practicality.

    Who can afford to spend $1,000 (for the ticket alone) on attending a two day event?

    Here’s the thing; unless you’re quite wealthy, or happen to work at a company that will cover the bill (most likely the case), my guess is that most of us simply can’t afford a random luxury weekend like this. Don’t feel badly; it doesn’t mean you’re not dedicated to your craft if you’re not able to fork over $1,000 to attend a conference. In fact, I’d argue that you’re a better person for taking such a stance, while ignoring the incessant conference-specific hash tags on Twitter.

    A $1,000 price tag for two days of lectures is exorbitant to the point of being vulgar.

    Are you Receiving $1k Worth of Education?

    This is the first question you should ask yourself before deciding to attend any conference that charges a high price tag: “Will I receive $1,000 worth of education?”

    A common mistake when attending a conference for the first time is assuming that you’re going to drive (or fly) home having greatly increased your understanding of a particular subject.

    If I can be so bold, though, you’ll likely find that this is not the case. Oh sure, you’ll come away with some neat new tips and tricks, but if your sole purpose for attending a conference is to “train,” then your money is much better spent elsewhere.

    For half the price – $500 – I can give you a stack of books and resources that will teach you the bulk of what you need to know to succeed as a web developer.

    In the defense of conferences, training is not their true focus. They’re much more geared for networking (and dare I say, vacations). If you do prefer training, then attend a workshop, which will be a fifth the cost, and five times as educational.

    A free open source community cannot survive without a touch of the commercial side to even things out.

    The talented Remy Sharp hosts workshops for roughly £200 – a far more appealing price tag. Remember, teachers shouldn’t be expected to work for free. I completely get that. The notion that everything in our industry should be free irks me a bit. A free open source community cannot survive without a touch of the commercial side to even things out.

    Let’s use the Tuts+ network as an example. We post roughly 40 free in depth tutorials every single week. The only way we’re able to offer that level of free training, though, is to supplement the sites with an optional Premium program that offers courses, video tutorials, etc. for $9 a month. These extra funds not only allow us to commission higher level, and more in depth tutorials, but they also provide us with the means to continue our primary objective: provide free education to the community. This simply would not be possible without our Premium program.

    Notice that our core goal is an admirable one. It’s not to make each editor and the company as rich as possible (though we wouldn’t be against it!). Instead, we want to change the landscape of education entirely. Our asking price is reasonable. I cannot say the same for some conferences, though.

    Are These Conference Organizers Bad?

    All this begs the question: are conference organizers, who charge these rates for a weekend event, bad people, or, at the very least, money hungry? Well, who are any of us to judge? That said, however, let’s consider a few points…for both sides of the argument.

    300 Attendees

    Assuming the $1k price tag that I’ve noticed around the web, let’s imagine that 300 people attend. That seems to be a reasonable figure, though I could be wrong. At this rate, the conference organizers will gross $300,000 for a weekend conference. This undoubtedly is a huge sum; however, we of course must consider the huge costs involved in planning this sort of event.

    • Rent the facility (certainly not cheap).
    • Pay airfare, food, and shelter for each speaker. This can add up, if they have around twenty speakers.
    • Pay each speaker. For many conferences – generally those which focus on open source platforms – the speakers offer their services free of charge (other than expenses). However, for a conference that charges $1,000 a ticket, the speakers most certainly receive a paycheck.
    • Design and print the t-shirts, banners, and programs.
    • Provide breakfast/lunch each day for all attendees.
    • Purchase advertisement spots in magazines and on the web.
    • Optionally arrange for an after party, with free drinks (usually two)
    • While many conferences are volunteer based, there will likely be staff involved.
    • Rent A/V equipment and wifi
    • A reasonable paycheck for the organizers. They shouldn’t be expected to work for free.
    • Surely, plenty else that I’ve missed…

    All of the above considered, though, do these expenses add up to $300,000? According to many conference organizers, the answer is yes. Of course, my personal response to that is, “If you require $300,000 to organize a modest two or three day conference, then maybe you’re reaching too high?”

    Assuming the organizers are honest people (which I’m sure they are), this must imply that the true cost of organizing an event is indeed expensive enough to the point that a $1000+ price tag is paramount. In Andy Budd’s response to this posting, he provides some first-hand reflection on the real (and expensive) cost of organizing a risky conference. These costs demand a large price tag in order to break even, it seems. But, at what point is the cost too high for the buyer? I’d vote for a cut-back, modest conference for $300 — that is, if I was paying for the event out of pocket. Nonetheless, these large events continue to sell out.

    What’s Wrong with Profit?

    All conferences are not created equal, so let’s assume that a handful of organizers are making a good chunk of change. Is there anything wrong with that? Absolutely nothing. As fellow author Jeremy McPeak put it: “…The web is becoming the platform of choice; so demand dictates the price.” Jeremy is certainly correct; demand 100% determines the cost. Why charge $1 when you can get $2?

    The various $1k-charging conferences that I see promoted on Twitter so frequently more often than not sell out.

    Maybe that’s what, as buyers, we should decide for ourselves; just because you can… doesn’t mean you should. Is the goal to push the web forward, or to make money? When you charge such an exorbitant price tag, you ensure that the huge majority of those, who would pay the ticket price out of their own pockets, won’t come…regardless of whether or not the expenses involved in arranging the conference warrant the price.

    Perk vs. Investment

    Companies offer conference trips as perks. In their eyes, they are investing in their staff. What’s $1,000 to a successful company? From the eyes of the staff member, he gets a fun vacation and the chance to network and learn a bit. Win win.

    I can’t help but feel, though, that this is somewhat unfair to those who must pay the entry price themselves. I’d wager that these are the folks who are most hungry for knowledge, yet the price tag virtually ensures that the doors are closed to them.

    The Question

    If it costs a buck, then it’s worth a buck, right?

    Perhaps it comes down to this single question: are some conferences simply an excuse to get your company to send you off on vacation, so that you can network with your internet buddies, and, again, learn a bit? The companies will blindly pay the cost, so why not charge four figures?

    We associate value with cost. If it costs a buck, then it’s worth a buck. The same must be true for conferences, right? But here’s the thing: some of these conferences are sold under the umbrella of “pushing the web forward.” To me, though, it seems that they’re much less concerned with education, and more with making money. When all is said and done, that’s not a bad thing. Who could blame them?

    I suppose you must decide for yourself if this is the sort of conference you want to participate in. Why are WordCamps">[2011.portland.wordcamp.org] generally only $50? The upcoming jQuery">[events.jquery.org] conference in Boston is $299 – a bit more, but still appropriately priced and reasonable. Airfare must be paid, staff must be compensated, food must be purchased.

    The going rate is $1,000 because people will pay it.

    My guess is that the true difference in cost stems from the fact that conferences like jQuery’s are less focused on making money, and more on raising jQuery’s awareness, teaching one another, and adding some funds to the project as a whole. Further, other than expenses, speakers don’t receive payment. For some other “professional” conferences though, this is not the case, and likely accounts for the increased cost. Your favorite internet celebrities don’t come cheap – nor should they. These guys have spent their entire adult lives acquiring the necessary skills to teach you. That demands some level of compensation. It all comes down to, however, whether or not this compensation comes at the cost of a huge price tag that you likely can’t afford. Then again, maybe such an event wouldn’t be possible with a cheaper ticket price. I find this hard to believe, but, it’s possible. As noted above, though, the going rate is $1,000 because people will pay it.

    Each of us is entitled to his own personal opinions. To my eyes, $300 is reasonable; $1000-$2000 is vulgar. This is especially true when there are countless community driven conferences that are equally fun and educational. But perhaps these professional conferences aren’t priced for you and me; they’re priced for the companies you work for. They’ll be footing the bill, right?


  • Permalink for 'Nettuts+ Builder: Free to Premium Members'

    Nettuts+ Builder: Free to Premium Members

    Posted: September 11th, 2011, 9:03am MDT by Jeffrey Way

    As we prepare Version 2 of our Nettuts+ Builder app, I’ve decided to make the initial release available free to all of our loyal Premium members.

    Nettuts+ Builder

    Free to Premium members, or $5 on CodeCanyon.

    Nettuts+ Builder turns the process of compressing scripts and stylesheets, and uploading a project to your server into as simple a process as possible.

    How’s It Work?

    Click the “Video Preview” button here to get a better understanding of how the App works.

    Let’s say that you finished a coding project or demo. Simply drag the folder onto the Builder menu icon, and it will:

    • Create a new “Publish” directory
    • Compress all JavaScript files
    • Compress all Stylesheets
    • Optionally upload them, via FTP, to a designated folder on your server.

    If you’ve found yourself manually compressing your files and uploading them to your server, this automates the entire process!

    What’s Coming Next?

    This app is being actively developed. Coming soon:

    • HTML compression.
    • Automatic concatenation of all scripts and stylesheets.
    • Automatic updating of HTML files with references to the newly concatenated assets.
    • Single file uploads
    • After uploading, a link to the url will be added to the clipboard.
    • Glossless image compression


  • Permalink for 'How to Install Ruby on a Mac'

    How to Install Ruby on a Mac

    Posted: September 7th, 2011, 9:08am MDT by Jeffrey Way

    This one is tailor made for the Basix users among you. If you’ve been itching to try out Ruby and/or Rails, if the Terminal is somewhat new to you, you may find that even the process of installing it can generate countless confusing errors. This article will detail the exact steps you need to follow to get Ruby up and running on your Mac.

    Step 1 – RVM

    What you might be interested to know is that Ruby comes preinstalled on your Mac. Don’t believe me? Open the Terminal and type:

    ruby -v
    

    Likely, the version number will return 1.8.7. While you might be tempted to stick with that, you probably shouldn’t for a couple reasons:

    • Old versions of the OS shipped with a buggy version of Ruby
    • RVM provides the flexibility to use any version of Ruby that you require. Plus, if you’re just starting out with Ruby, don’t use an old version; you want 1.9.2!

    These days, RVM is the way the cool kids install Ruby, and that’s what we’ll use.

    “RVM lets you deploy each project with its own completely self-contained and dedicated environment–from the specific version of ruby, all the way down to the precise set of required gems to run your application. Having a precise set of gems also avoids the issue of version conflicts between projects, which can cause difficult-to-trace errors and hours of hair loss. “

    Open the Terminal, and type:

    bash < <(curl -s [https:] 

    If an error is returned when you run this command, make sure that you have Git installed. Don’t worry, it’s easy to setup!

    Step 2 – Load RVM into the Shell

    Give that a few seconds to install, and next, we need to make RVM available to the shell. We’ll do this by updating our ~/.bash_profile file.

    cd ~/
    sudo vim .bash_profile
    

    Note that we’re using Vim to update this file, which can be a bit confusing at first. Feel free to open this file in any code editor your prefer. Maybe you want to use mate .bash_profile. Also, note that, if this file does not exist, you should create it manually. Paste the following to the bottom of the page.

    [[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm"  # This loads RVM into a shell session.
    

    If you’re using Vim, you’ll need to press i to switch into Insert Mode first. Once the line has been pasted, press Escape, and then :wq! to save and close the file. If you’re using a different code editor, then you know what to do!

    Step 3 – Restart Terminal

    Just to be safe, let’s restart Terminal to make sure that everything took effect. To ensure that RVM is correctly installed, type:

    rvm
    

    You should see a long list of commands that are available to you. Good job; that part is out of the way.

    Step 4 – Download the Latest Version of Xcode

    From my experiences, the biggest gotcha is when you try to install a new version of Ruby with RVM, and you’re met with a handful of confusing errors. Most of the time, this is the result of Apple’s Xcode not being installed on your system, or, if it is, not being the current version.

    You can download Xcode from Apple’s App Store. Search for “xcode” and click the install button.

    Download XCode

    You might want to fix yourself some lunch, as this large file will take some time to download. Once it does, though, run the install process, and, when finished, close Xcode. You shouldn’t need to restart your computer, but, if it keeps you in the good graces of the church, go ahead and do so.

    Step 5 – Download Ruby 1.9.2

    Next, restart Terminal, and type:

    rvm list known
    

    You’ll see a long list of versions…

    $ rvm list known
    # MRI Rubies
    1.8.6[-p420]
    1.8.6-head
    1.8.7[-p352]
    1.8.7-head
    1.9.1-p378
    1.9.1[-p431]
    1.9.1-head
    1.9.2-p180
    1.9.2[-p290]
    1.9.2-head
    ruby-head
    ...
    

    For our needs, let’s install Ruby 1.9.2

    rvm install 1.9.2
    

    That shouldn’t take but a moment.

    If you still receive an error at this point, leave a comment below with your error message, and the rest of us will help you debug it. But, before doing so, type: rvm notes to determine if you’ve forgotten to install any dependencies.

    Once the installation has completed, we need to tell RVM which version of Ruby we currently want to use:

    rvm use 1.9.2
    

    Next, test it by checking the version number:

    ruby -v
    

    On my computer, this returns ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0]. Good job, you’re now using Ruby 1.9.2. There’s just one last thing to deal with.

    Step 6 – Make 1.9.2 the Default

    If you restart Terminal, and type ruby -v again, you’ll likely find that it has defaulted back to the system version of Ruby: 1.8.7. That’s no good! Let’s be sure to make 1.9.2 the default.

    rvm --default use 1.9.2
    

    This bit is identical to what we did just a moment ago – the only difference being that we’ve specified that 1.9.2 should be the default.

    Step 7 – Finished. Begin Installing Gems

    And that’s it! You’re all set to go! If you’d like to experiment with Ruby’s syntax, type:

    irb
    2 + 2
    

    The next step is to install any gems that you require. For example, if you want to work with Ruby on Rails:

    gem install rails
    

    Or possibly Sinatra:

    gem install sinatra
    

    Important: Note that I’m not using sudo to install these gems. This is a big no-no when working with RVM. From the official docs:

    “When you do sudo you are running commands as root, another user in another shell and hence all of the setup that RVM has done for you is ignored while the command runs under sudo (such things as GEM_HOME, etc…). So to reiterate, as soon as you ‘sudo’ you are running as the root system user which will clear out your environment as well as any files it creates are not able to be modified by your user and will result in strange things happening. (You will start to think that someone has a voodoo doll of your application…)”

    Conclusion

    If this tutorial seemed incredibly easy to you, that’s because it wasn’t intended for you. Not everyone is comfortable with the command line, and not everyone installs Ruby without first being met with a huge crop of errors. Hopefully, this article will help a bit. And, again, if you’re still having trouble, leave a comment, and we’ll do our best to help you out!

    Alternatively to RVM, you also might look into rbenv, which, though quite new, is quickly gaining popularity.

    You Also Might Like…


  • Permalink for 'The Burden of File Synchronization'

    The Burden of File Synchronization

    Posted: September 6th, 2011, 9:22am MDT by Jeffrey Way

    First world problem alert! If you have the luxury of using two computers for your day-to-day coding – for example, a desktop for the office, and a laptop for home – you’ve likely found yourself complaining (or cursing) when your files aren’t syncing correctly.

    Why can’t my laptop be an exact mirror of my desktop?

    I know I have! I’ve even thought to myself, “Why can’t my laptop be an exact mirror of my desktop?” Well, there are ways to accomplish this, but, they’re time consuming and aren’t as consistent as you might hope. Nonetheless, let’s review a few ways that we can sync two computers.

    Sync your Home Directory with Dropbox

    It’s likely that all of us use Dropbox to some extent. The default installation will create a ~/Dropbox directory; however, we can also use “Selective Sync” to define which folders should be watched.

    Selective Sync

    Now, we could sync our entire home directory, as exemplified in the image above. There are still potential concerns with this method though:

    1 – Space ain’t free, yo!

    The basic free Dropbox plan offers 2GB of space – in other words, not very much. If you intend to sync your entire Home directory, you’ll need to commit to either the 50GB or 100GB plans, which will run you $120 or $240 a year, respectively. Yikes! Even worse, if you’re like me, you’ll find that even 100GB isn’t enough.

    Dropbox Plans 2 – Endless Syncage

    If you do choose to sync your entire home/ directory, you may find that, seemingly at all times, Dropbox is syncing. Download an iTunes movie on your laptop, and, when you turn your desktop computer on, it’ll take an hour to download that one large file. This can be incredibly irritating. Also, while, as I understand things, the process of downloading a large file shouldn’t interfere with small documents being synced at the same time, I’ve found that it often does. If I save a Word document on my laptop, sometimes it can be a good wait before it shows up on my other computer.

    All of these small irritations quickly add up.

    3 – CPU Intensive?

    I must admit that this one is a bit odd. I’ve noticed that, at some points, Dropbox can be a bit hard on my CPU. After checking my computer’s Activity Monitor, I’ve found Dropbox taking up as much as 30% of my CPU, dramatically reducing my computer’s performance.

    All that said, this seems to be a sporadic effect. As I write this article, while syncing, Dropbox is using less than 1% of my CPU. It’s certainly odd. Maybe you guys have some notes in the comments?

    Use Synchronization with GoodSync GoodSync

    If you require a cheaper way to sync your files, you might look into GoodSync, which allows you to create any number of jobs (free edition is limited to three). For example, I could create a job which, each day, copies all of the files from a particular directory on my desktop over to my laptop. Alternatively, I could also instruct GoodSync to actively watch my Desktop directory and copy files over in real-time. If you choose this route, note that it can affect your computer’s performance a bit.

    The obvious advantage to using GoodSync is that you’re not paying a monthly fee.

    The service even makes the process of locating the various computers in your local network as easy as possible. If you sign into GoodSync on each computer, your file system will automatically be available across all computers.

    Up until now, this is the method that I had been using. It certainly works, but, again, there are sporadic hiccups. Most notably, I still have to wait for the necessary files to copy over, and, again, from time to time, the app seems to falter and miss certain triggers.

    It’s Difficult to Sync Settings

    While some apps allow us to sync configuration settings and databases, via Dropbox, others do not. For instance, let’s consider an app that allows you to save commonly used snippets (Snippets in my case). You’ve likely found frustration in the fact that a snippet you save to your laptop’s version of Snippets will not be available on your desktop.

    Snippets specifically allows you to sync your XML database via MobileMe, but most of us don’t use it – so, back to the drawing board.

    The Common Solution

    On the Mac specifically, the frequently advertised solution is to create a symlink.

    So let’s do one together; our job is to sync the database for Snippets across our two computers with Dropbox. This database XML file will be stored within ~/Library/Application\ Support/Snippets.

    First, cd/ to the Application Support directory, mentioned above.

     cd ~/Library/Application\ Support
    

    Next, we’ll copy the Snippets directory over to Dropbox. If you’re not syncing your entire home directory, keep things clean and create an Application Support directory in the root of your Dropbox folder.

     mv Snippets ~/Dropbox/Application\ Support
    

    Now, we’ll create a symlink. Make sure you’re still within the ~/Library/Application\ Support/Snippets directory, and type:

     ln -s ~/Dropbox/Application\ Support/Snippets Snippets
    

    To better understand this line, think of it as: ln -s [path/to/directory/to/sync] [path/to/new/folder].. This code creates a symbolic link, which allows us to store Snippets’ database on Dropbox, but still function as expected. The app will want to find these files in the Application Support/ directory, and this method allows for that.

    Repeat these steps for each computer, and then test it! Create a new snippet on your laptop, and watch it show up on your desktop, after Dropbox syncs the file.

    So sure, this method works; but it’s not perfect.

    1. It’s time consuming. Will you do this for each app, or symlink your entire Application Support directory?
    2. Not all apps can be synchronized this way. For example, Quicken will kick up a fuss if you use this technique. I’ve yet to find a way to get Quicken to play nicely across multiple computers. There are countless forum threads on this particular topic. It’s easier to use Mint.com, if it’s available where you live.
    Why Complicate Things?

    One day, not more than a week ago, as I found myself, again, wishing that my laptop was a mirror for my desktop, I realized that I was complicating things. Why do I need two separate harddrives? How much time have I wasted researching synchronization tools?

    From today on, I am now a “one computer” man. I’ve sold my iMac and laptop, and have replaced them with a 15 inch Macbook Pro and a Thunderbolt display. When I’m in my office, I connect the laptop to my monitor, work in the glorious 27 inch fashion that I’ve grown accustomed to. And when, I’m on the couch, or – gasp… in bed working – the laptop is disconnected, and it’s business as usual.

    No more synchronization, no more complaining, no more hassles. It took me years to choose the most obvious solution.

    My Question for You Is…

    If you are in a similar position, how do you personally deal with the burden of file synchronizing?


  • Permalink for 'How to Integrate rspec into a Sinatra App'

    How to Integrate rspec into a Sinatra App

    Posted: August 30th, 2011, 3:01pm MDT by Jeffrey Way

    In today’s video tutorial, I’m going to teach you how to use rspec within a Sinatra application. Along the way, we’ll also arrange for autotesting with Growl notifications so that our tests run automatically when we save our projects. If you’re quite new to the idea of testing, this is the perfect introduction.

    Choose 720p for optimal viewing.
    Subscribe to our YouTube and Blip.tv channels to watch more screencasts. We’ll Cover…
    • Installing rspec
    • Integrating rspec into a Sinatra application
    • The basic syntax for rspec tests
    • Enabling Growl notifications
    • Autotesting


  • Permalink for 'Sublime Text 2 Tips and Tricks'

    Sublime Text 2 Tips and Tricks

    Posted: August 29th, 2011, 1:03pm MDT by Jeffrey Way

    Sublime Text 2 is one of the fastest and most incredible code editors to be released in a long time! With a community and plugin ecosystem as passionate as this one, it just might be impossible for any other editor to catch up. I’ll show you my favorite tips and tricks today.

    Sublime Text 2 is currently available for all major platforms: OS X, Linux and Windows.

    1 – Bleeding Edge Versions

    Sublime is in active development. If, like me, you want to use the latest possible version of the app, you can download the dev build. You’ll find that new (auto) updates are available every other day or so.

    Download a dev build of Sublime 2 here.

    2 – Get a Better Icon

    In its defense, Sublime Text 2 is still in a beta state. The official icon will likely/hopefully change with the official release. Until then, Nate Beaty created an alternative icon, if you prefer it.

    Sublime Icon

    To integrate it, you need to replace the existing “Sublime Text 2.icns” file with this new one. On a Mac, browse to Sublime 2 in your Applications/ folder, then right-click and “View Package Contents.” Lastly, browse to Contents/Resources/, and drag the new icon in, overwriting the existing one.

    Please take note of the fact that, if you’re using the frequently updated development version of Sublime Text, with each update, the icon will be removed. With that in mind, don’t worry about the icon for the time being.

    3 – Access the Command Palette

    Similar to TextMate, we can use Sublime’s command palette by accessing the Tools menu, or by pressing Shift + Command + P, on the Mac. Whether you need to visit a Preferences page, or paste in a snippet, all of that can be accomplished here.

    Access the command palette 4 – Lightning-Fast File Switching File Switching

    Press Control or Command + P, type in the name of the file you wish to access (fuzzy finder), and, without even pressing Enter, you’ll instantly be transported to that file. While Vim and apps like PeepOpen offer a similar functionality, they’re not nearly as fast as Sublime’s implementation.

    5 – How Did We Survive Before Multi-Selection?

    Editors like TextMate have long offered vertical selection, which is quite neat. But, with multi-selection, you can have multiple cursors on the page. This can drastically reduce the need for using regular expressions, and advanced search and replace queries. Perhaps a quick visual demonstration is in order…

    To enable multi-selection, you have several options:

    • Press Alt or Command and then click in each region where you require a cursor.
    • Select a block of lines, and then press Shift + Command + L.
    • Place the cursor over a particular word, and press Control/Command + D repeatedly to select additional occurrences of that word.
    • Alternatively, add an additional cursor at all occurrences of a word by typing Alt+F3 on Windows, or Ctrl+Command+G on the Mac. Amazing!!
    6 – Indent Guides

    Update: this feature now comes preinstalled with Sublime Text 2.

    It’s such a small feature, but I’ve always loved how Notepad++ on Windows displays indent guides; it makes the page much easier to navigate and format. Sublime Text 2 offers this ability, via a plugin created by Nikolaus Wittenstein.

    Indent Guides

    To integrate this plugin:

    • Download it
    • Rename the folder to “Indent Guides” and drag it into the Packages folder. On a Mac, this path would be Application Support/Sublime Text 2/Packages
    7 – Package Control

    The steps outlined in the previous tip (#6) are a bit tedious, aren’t they? Instead, we can install the excellent Sublime Package Control, which streamlines the entire process.

    To install “Package Control,” open Sublime and press Control + `. Next, paste the following snippet into the console.

     import urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp) if not os.path.exists(ipp) else None;open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read())
    

    Don’t worry if you don’t understand the code above; just copy and paste!

    Console

    Lastly, restart Sublime Text, and browse to Preferences -> Package Settings. If the installation was successful, you’ll now see a Package Control item in that list.

    With Package Control installed, the process of adding new plugins and functionality becomes incredibly simple!

    For a usage example, refer to the next item in this list.

    8 – Alignment

    If you’re the type who prefers to line up your equal signs – for example, in your JavaScript…

    // Before
    var joe = 'joe';
    var johnny = 'johnny';
    var quaid = 'quaid';
    
    // After
    var joe    = 'joe';
    var johnny = 'johnny';
    var quaid  = 'quaid';
    

    …this process can be automated, via the Sublime Alignment plugin. Rather than downloading and installing it manually, let’s instead use Package Control (outlined in #7).

    • Press Shift + Command + P
    • Type “install,” to bring up the “Package Control: Install Package” option, and press Enter
    • Look for “Alignment,” and press Enter to install it.
    • You’re done; so easy! Type Shift + Command + A to auto-align.
    Auto-align

    This process can be repeated for all of the typical plugins we install, such as Zen Coding.

    9 – Vim Fanatic

    I’m a huge fan of Vim. The amount of power it provides is insane. The fact that I’ve switched over to Sublime Text 2 should speak volumes then!

    If you’re using a dev build of Sublime Text (see #2 in this list), you can enable Vintage mode, which provides support for the Vi commands that we know and love — okay…some of us love. The rest of you hate it! :)

    To enable Vintage mode, browse to Preferences/Global Settings - Default. Once this file opens, browse to the very bottom, and change "ignored_packages": ["Vintage"] to "ignored_packages": []. Next, restart Sublime, press the Escape key, and, tada: command mode!

    Block Cursor

    One thing you may notice is that, in command mode, it can be difficult to find the cursor (especially when taking advantage of things like bookmarks). On more than one occasion, I’ve found myself trying to hunt down its location.

    While it’s not a perfect solution, a plugin, called “SublimeBlockCursor,” attempts to remedy this issue.

    Note: While the readme states that SublimeBlockCursor can be installed, via Package Control, I wasn’t able to find it. Instead, I had to clone the project manually into the Packages folder.

    10 – Distraction Free Editing

    Sometimes, we need to filter out all of the additional fluff that gets in the way of our coding. Use “Distraction Free Mode” to take this idea as far as possible. This option is available, via the View menu. Select “Enter Distraction Free Mode,” or use the Mac keyboard shortcut, Control + Shift + Command + F.

    Distraction Free Mode 11 – You Can Still Use TextMate Bundles

    Slim

    TextMate snippets and themes port over nicely to Sublime Text. You only need to drop them in the Packages folder — .tmbundle extension intact, and Sublime will recognize the files. This means that the entire catalog of TextMate themes will work in Sublime!

    For example, I’ve been working with the (fantastic) Slim templating engine a good bit lately, and needed better syntax highlighting. Fred Wu created a bundle for TextMate, but, tada, it works perfectly in Sublime Text as well! If you’re interested, you can download the Slim bundle here; it includes both snippets and syntax highlighting.

    12 – Custom Themes

    The default theme for Sublime Text is excellent, but I much prefer a custom light and dark theme, Soda, created by Ian Hill.

    Soda Theme Installation

    As taken from the Github page…

    “If you are a git user, the best way to install the theme and keep up to date is to clone the repo directly into your Packages directory in the Sublime Text 2 application settings area.”

    Using Git

    Go to your Sublime Text 2 Packages directory and clone the theme repository using the command below:

     git clone [https:] "Theme - Soda"
    
    Download Manually
    • Download the files using the GitHub .zip download option.
    • Unzip the files and rename the folder to Theme – Soda
    • Copy the folder to your Sublime Text 2 Packages directory
    Activating the Theme

    To configure Sublime Text 2 to use the theme:

    • Open your Sublime Text 2 User Global Preferences file: Sublime Text 2 -> Preferences -> User Global Settings
    • Add (or update) your theme entry to be “theme”: “Soda Light.sublime-theme” or “theme”: “Soda Dark.sublime-theme”
    Example User Global Settings
    {
        "theme": "Soda Light.sublime-theme"
    }
    
    13 – Page Crawling

    Sublime Text provides us with a few different ways to query a page (outside of the standard search functions).

    Functions

    Need a quick way to browse to a specific function or method?

    Function Crawling

    Type Control/Command + r to reveal a popup that allows for this very thing (notice the @ symbol)! Even better, the search is fuzzy as well, which is particularly helpful for huge classes.

    HTML

    What if you want to immediately transition to a specific part of an HTML page – say, to the div with a class of container. Type Control/Command + p, then #, and you’ll instantly see a tree of your document.

    Go To Line Number

    To quickly move to a specific line number on the page, you can press Control + g. However, you’ll notice that, once again, it’s pulling up that palette (Control/Command + p), and appending the : symbol. This is adopted from Vim.

    This means, in addition to Control + g, you can also type, Control/Command + p, and then :LINE_NUMBER.

    14 – Fetch Remote Files with Ease

    Nettuts+ Fetch

    Let’s say that you’re a fan of Normalize.css. Perhaps, you download it and save it to a snippet, or store the stylesheet, itself, in an assets folder. That way, for future projects, you only need to copy and paste.

    The only problem with this method – as we’ve all discovered – is that, if a few months have passed, it’s more than possible that the asset (in this case, Normalize.css) will have been updated by the creator. So your options are to either use the, now, out-dated version of Normalize, or, once again, return to the GitHub page and pull in a fresh copy. This all seems tedious.

    Created by Weslly Honorato, Nettuts+ Fetch is the solution to our dilemma. It can be installed, via Package Control.

    Usage

    You’ll only use two commands, when working with Fetch. First, we need to save some file references. Again, bring up the command palette, and search for “Fetch.” For now, choose “Manage Remote Files.”

    Manage Remote Files

    What’s great about Sublime Text 2 is that configuration is incredibly simple. To assign references to online asset files, we only need to create an object, like so (don’t worry; one will be pre-populated for you, after installation):

    So, to pull in the latest copy of jQuery (if you don’t want to use a CDN):

    {
    	"files":
    	{
    		"jquery": " [code.jquery.com] 	}
    }
    

    Learn more about using Nettuts+ Fetch.

    15 – Prefixr Plugin

    Built by by Will Bond (creator of Package Control), the Nettuts+ Prefixr plugin allows you to automatically update your entire stylesheet to include support for all of the various required CSS3 vendor prefixes. This way, you never have to visit the website itself; you merely type a keyboard command, and:

    .box {
       border-radius: 10px;
       box-shadow: 0 0 5px rgba(0,0,0,.4);
    }
    

    …will be converted to:

    .box {
    	-webkit-border-radius: 10px;
    	-moz-border-radius: 10px;
    	border-radius: 10px;
    
    	-webkit-box-shadow: 0 0 5px rgba(0,0,0,.4);
    	-moz-box-shadow: 0 0 5px rgba(0,0,0,.4);
    	box-shadow: 0 0 5px rgba(0,0,0,.4);
    }
    
    Usage

    Once installed (via Package Control), select your stylesheet (or a single block), press ctrl+alt+x on Windows and Linux, or cmd+ctrl+x on OS X, and the code will instantly be run through the Prefixr web service.

    16 – Launch Sublime From the Terminal

    Sublime Text 2 includes a command line tool, subl, to work with files on the command line.”

    To use it, create a symlink to the tool.

    ln -s "/Applications/Sublime Text 2.app/Contents/SharedSupport/bin/subl" ~/bin/subl
    

    As long as ~/bin is in your path, that should do the trick!

    cd myProject
    subl .
    

    Refer here for additional instructions.

    17 – Autoformat HTML

    A bit oddly, the ability to auto-format HTML is not included as part of the default build of Sublime Text. The Tag plugin, among other things, hopes to provide a solution, however, due to a few shortcomings – namely when dealing with HTML comments – it falls short.

    The Tag plugin can be installed via Package Control.

    To test its auto-formatting skills, the following HTML:

    <html>
    <head>
    	<meta charset=utf8>
    	<title></title>
    	<!-- begin-->
    
    	<!-- end comment -->
    </head>
    <body>
    
    <h1>Hi there</h1>
    
    <h2>Bye</h2>
    </body>
    </html>
    

    …will be changed to:

    <html>
    	<head>
    		<meta charset=utf8>
    		<title></title><!-- begin-->
    <!-- end comment -->
    	</head>
    	<body><h1>Hi there</h1>
    
    		<h2>Bye</h2>
    	</body>
    </html>
    

    Yikes; it looks worse than it is. From my tests, it incorrectly does not place the body tag on its own line, and gets pissy when dealing with HTML comments. Until these issues are fixed (or a native solution is provided), it’s best to manually select a block of HTML to reformat, rather than the entire page.

    A $200 bonus will be paid to the first Sublime Text plugin developer who creates and submits the definitive “Nettuts+ HTML Formatter” plugin.

    18 – Create a Plugin

    If you’re feeling adventurous, dig into Sublime Text’s huge plugin development community, and start contributing. We have an excellent tutorial on the process of building a ST plugin here on Nettuts+. Be sure to check it out if that interests you!

    Conclusion

    The more I work with Sublime Text 2, the more I realize how incredible it is. But all of this would mean nothing if not for the fact that it’s an insanely fast editor, and, even better, it’s not finished!


  • Permalink for '11 Tools to Instantly Code Faster'

    11 Tools to Instantly Code Faster

    Posted: August 23rd, 2011, 11:38am MDT by Jeffrey Way

    Twice a month, we revisit or update some of our readers’ favorite posts and sessions from throughout the history of Nettuts+. This tutorial was first published last September.

    Doesn’t the title say it all? There are a wide variety of tools and techniques which can drastically improve the speed at which we code. Particularly during time-sensitive settings, even a savings of a few seconds per iteration can add up substantially over the course of the month. I’ll show you eleven of my favorite tools in this article.

    1. Zen Coding

    Combine the power and specificity of CSS selectors with HTML mark-up, and you get Zen Coding. Certainly, I wasn’t the only one whose jaw dropped the first time he saw:

    div#container>div#contents>ul#nav>li*4

    …convert to:

    <div id="container">
    	<div id="contents">
    		<ul id="nav">
    			<li></li>
    			<li></li>
    			<li></li>
    			<li></li>
    		</ul>
    	</div>
    </div>
    

    In this last year, the Zen Coding project has gained considerable attention, and has been expanded to support a wide variety of code editors, including Espresso, Vim, Netbeans, TextMate, and Komodo Edit.

    “Zen Coding is an editor plugin for high-speed HTML, XML, XSL (or any other structured code format) coding and editing. The core of this plugin is a powerful abbreviation engine which allows you to expand expressions—similar to CSS selectors—into HTML code.”

    Alternatives 2. Split Windows

    For many, a simple tab-based coding experience is more than adequate; however, others prefer a more integrated approach. Unfortunately, the ability to split windows is not widely available across code editors. Luckily, though, a handful of them do support it at varying levels of flexibility (the king being Vim).

    Vim

    The excellent Vim editor offers an unprecedented level of window combinations. Use :sp and :vsp to create new windows from within normal mode.

    Alternatives 3. Embrace Social Coding

    In the last two years particularly, the idea of social coding has gained considerable popularity – and why wouldn’t it? If it’s fun to share photos on Flickr, the same will of course be true for coding. With site likes Envato’s recently purchased Snipplr, Github, or Forrst, not only can you manage your own snippets for future use, but you can also take advantage of multiple brains by receiving community feedback on your coding techniques and choices.

    Snipplr

    Envato recently purchased the popular Snipplr.com

    Another social networking site? Yes, that is true; but, I must admit: it’s fun. Plus, it’s educational!

    4. Code Management Tools

    Online networks like Github, Snipplr, and Forrst are fantastic, however, they can be time consuming to access, when you need to reuse a specific piece of code (assuming it’s not already part of a bundle). The solution is to install one of the various code management applications available around the web.

    Personally, as a Mac user, I prefer the not-free Snippets app.

    Snippets App

    With this tool, when I’m working on code, I can simply press, on the Mac, Command + F12 to insert my desired code snippet into my project. Even better, it integrates an “Export to Snipplr/Snipt/Pastie” feature that’s extremely useful.

    Share with Snipplr

    While many editors offer an integrated snippets utility, I’d recommend embracing a third party tool instead. This way, your snippets aren’t limited to a single editor.

    Pro Tip

    If you want to sync your snippets across all your computers, via Dropbox, you can create a symlink.

    • Step 1: Browse to ~/Library/Application Support/Snippets.
    • Step 2: Copy the entire folder to Dropbox.
    • Step 3: Create a symlink. In the Terminal, type: ln -s ~/Dropbox/Snippets ~/Library/Application Support/Snippets .
    • Step 4: Rinse and repeat for all of your computers.
    What Sorts of Snippets Should I Save?

    Everything you can think of! As a rule of thumb, if you tend to type some block of code more than once, save it. Let’s do an obvious one together; when producing a new website, how often do you type out the three lines or so to create rounded corners in the modern browsers?

    #box {
     -moz-border-radius: 3px;
     -webkit-border-radius: 3px;
     border-radius: 3px;
    }
    

    This takes around ten seconds to type each time. What a waste! Instead, create a new snippet, and reduce your coding time by 90%.

    Alternate Options 5. Choose a Proper Editor

    The Holy Grail of efficient coding; your choice of code editor will have the largest effect on your coding speed. Unfortunately, there isn’t a definitive answer. Your decision will largely be dependent upon:

    • Which languages you code in
    • Your OS
    • The type of UI you prefer
    • Comfort with the command line (or lack of)

    As an example, someone who predominantly creates HTML themes for a site like ThemeForest would be unwise to use a full IDE like Aptana. It’s simply unnecessary and too slow. However, the same is not true for a server-side developer.

    Questions to Ask Before Deciding on an Editor
    • How important is speed? Should the editor open nearly instantly?
    • Do I require integrated debugging tools?
    • Does this editor offer some form of bundle functionality?
    • How easy to memorize are the keyboard shortcuts?
    • Are my favorite extensions and plugins (like Zen Coding) available for this code editor?
    • Do I require integrated Git logging?
    • Am I okay with a GUI interface?
    • Do I prefer speed over visuals…or Vim over Coda?

    When I asked myself these questions, I determined that speed and performance were paramount. As such, I currently use Sublime 2 and Vim. The latter is significantly daunting at first, but provides an unprecedented level of flexibility and speed, due to the fact that even traversing your page requires a language, of sorts. However, for larger projects, which require debugging, I use Netbeans.

    6. Use Bundles

    Bundles: learn them…use them. Editors, like TextMate — and, subsequently E Text Editor — popularized bundles; however, they’re widely available from editor to editor.

    What’s So Great About Them?

    How many times have you found yourself typing the same generic piece of mark-up or code, whether that might be a new function, or the structure of a new jQuery plugin. How much time are you wasting each time you repeat this process? This is where bundles come into play.

    For example, by downloading the TextMate CodeIgniter bundle, we can take advantage of a wide array of methods and snippets. Remember – less typing is always a good thing!

    CodeIgniter Bundle

    With this bundle installed, we only need to type the designated shortcut, and then press tab (in most editors). This will then expand the shortcut into the requested code. What separates a bundle from a snippet is that you can specify multiple tab stops to further expedite your coding speed.

    Vim Users: if you miss/envy the TextMate bundle feature, check out the SnipMate plugin.

    7. Use a CSS Preprocessor

    Tools like LESS.js and Sass can drastically increase your coding speed. In terms of which one to choose: they’re both excellent. These days, I tend to prefer Sass, since the Compass framework is built on top of it, and provides an unparalleled number of convenience functions. It also seems to be what the cool kids use. )

    How Does it Work?

    These tools allow for all of the features that you wish CSS had — such as variables and functions.

    /*
    Variables!
    */
    @primary_color: green;
    
    /*
    Mix-ins are like functions for commonly used operations,
    such as apply borders. We create variables by prepending
    the @ symbol.
    */
    .rounded(@radius: 5px) {
    	-moz-border-radius: @radius;
    	-webkit-border-radius: @radius;
    	border-radius: @radius;
    }
    
    #container {
    /* References the variable we created above. */
    	background: @primary_color;
    
    /* Calls the .rounded mix-in (function) that we created, and overrides the default value. */
    	.rounded(20px); 
    
    /* Nested selectors inherit their parent's selector as well. This allows for shorter code. */
    	a {
    		color: red;
    	}
    }
    

    Pro Tip: To make your browser update every time you save a file (very handy feature), use the watch method. Place the following at the bottom of your project. Of course, this assume that you’ve already setup LESS.js.

    less.env = 'development';
    less.watch();
    
    LESS Compiler

    Many might argue that it’s unsafe to use a JavaScript-based solution. But that’s okay; there are a handful of compilers available around the web. The best solution I was able to find is called LESS.app.

    LESS APP

    After you download it (free), you simply drag your project folder into the app, which instructs it to watch all .LESS files. At this point, you can continue working on your project, per usual. Every time you save, the compiler will run, which generates/updates an automatically created style.css file. When you’re finished developing your app, you only need to change your stylesheet references from style.less to style.css, accordingly. Easy! Now there’s no reason not to take advantage of LESS — unless you’re using a different solution, like Sass.

    Take our mini-series to learn exactly how to work with Sass.

    Generates CSS FIle 8. Prototype Early with Firebug

    You know the drill: write a bit of JavaScript, switch and refresh your browser, receive an error, return to the editor…and rinse and repeat. Though we all do it, sometimes, there are far more efficient alternatives, such as protoyping early with tools like Firebug. By working directly in the browser, you cut out the middle man, so to speak.

    The uber-talented Dave Ward recommended this tip, and has even created a screencast demonstrating this method.

    Visit Dave’s website to view a higher quality version of this screencast.

    9. Use Prefixr Prefixr

    Tools like Compass, or even a TextMate bundle are tremendously helpful – I use them often, actually. But, for many projects, they aren’t available. As a result, we’re left in the position of having to copy and paste over, and over…and over.

    I built Prefixr to do all this tedious work for me. Simply paste in your stylesheet, press Prefixize (or hit Control + Enter), and Prefixr will filter through the applicable CSS3 properties and dynamically update them.

    Can’t remember if Opera provides a prefixed version of, say, the transition property (o-transition)? Don’t worry about it; that’s already coded into Prefixr!

    With Prefixr, you only code your stylesheets using the official W3C-recommended markup. When ready for deployment, run the stylesheet through Prefixr, and be done with it!

    Learn more about Prefixr.

    10. Find an Editor that Offers Multi-Select

    I’ll first warn you that very few code editors offer a multi-select feature. The editor that I currently use, Sublime 2, does though. Even better, it’s available for both Windows and Mac users.

    So what exactly is multi-selection? Well, editors like TextMate have long offered vertical selection, which is quite neat. But, with multi-selection, you can have multiple cursors on the page. This can drastically reduce the need for using regular expressions, and advanced search and replace queries. Perhaps a quick visual demonstration is in order…

    11. Don’t Reinvent the Wheel

    When first getting started in this field, I always took issue with comments like “Don’t reinvent the wheel.” It’s not about reinvention; it’s about understanding how the wheel functions. However, once you know the inner workings of the wheel, this argument certainly is true: Don’t Repeat Yourself.

    Coding each new project from scratch is incredibly time consuming.

    If you want to complete new projects as quickly as possible (and who doesn’t), save yourself some time, and take advantage of the various levels of abstractions that are available around the web. A handful of my favorites include:

    • HTML5 Boilerplate – Whether you choose to use this template in its entirety, or in bits and pieces, it doesn’t matter. Just use it! And while you’re at it, split the sections of code into snippets for reuse! Watch the official guide to Boilerplate on Nettuts+
    • CodeIgniter (PHP Framework) – For higher level PHP applications, the CodeIgniter framework is a fantastic choice. Even better, the community support is second to none. If you happen to be a visual learner, our CodeIgniter from Scratch series is, also, second to none. )
    • 960 (CSS Framework) – If you require grid-like structures, both the 960 and Blueprint CSS frameworks are fantastic choices. They easily turn hours of work into a two minute process; and, if you’re worried about file bloat, you needn’t. That’s a ridiculous argument. Let us teach you how to use 960!
    • jQuery (JavaScript Library) – Does this one really require explanation at this point? Save yourself the headaches, and use it (that is, unless you’ve developed your own awesome library).
    Conclusion

    I’ll show you mine if you show me yours. Which tools and resources do you use to code faster?


  • Permalink for 'How to Use the Nettuts+ Phing Build Script'

    How to Use the Nettuts+ Phing Build Script

    Posted: August 19th, 2011, 2:37pm MDT by Jeffrey Way

    We’ve created a build script for Phing that will give designers the ability to automatically compress, concatenate, and Prefixize all of their stylesheets and scripts — simply by typing five characters. I’ll show you how to use it in this quick tip video.

    Choose 720p for optimal viewing.
    Subscribe to our YouTube and Blip.tv channels to watch more screencasts. Coming Soon
    • Optimize all images
    • Clean up and remove unnecessary element attributes
    That’s It

    As you can see from the video above, it’s incredibly easy to use the Nettuts+ build script. Just install Phing, download the build directory, and run phing from the command line! Even better, if you’re a PHP developer, you can extend Phing quite easily. Be sure to refer to our Premium course if that intrigues you.

    If you notice any bugs, let me know in the comments, and I’ll get those fixed ASAP!


  • Permalink for 'Killer Build Scripts with Phing: Premium Course'

    Killer Build Scripts with Phing: Premium Course

    Posted: August 15th, 2011, 1:26pm MDT by Jeffrey Way

    In this 12-part Premium screencast course, I’m going to teach you exactly how to work with the popular build script tool, Phing. Phing allows us to automate so many of the things we do manually for each project, such as compressing and concatenating code, FTPing files, and pushing projects to GitHub. When you’re ready to dig in, just push play!

    Become a Premium member to download this course, as well as hundreds of other advanced tutorials and screencasts.

    Premium Course Introductory Overview Course Overview
    1. Introduction
    2. Installation and your First Build Script
    3. Declaring Properties
    4. Creating and Deleting Directories
    5. Copying Files with Filesets
    6. Compressing CSS Files
    7. Compressing JS Files
    8. Concatenating Files
    9. Compressing HTML and Using Selectors
    10. Using Regular Expressions to Update an HTML Page
    11. Creating Adhoc Tasks
    12. PHP, Regular Expressions, and Completing our Project
    Join Net Premium NETTUTS+ Screencasts and Bonus Tutorials

    With over two hours of training, there’s no way you won’t become a Phing pro in no time. Let’s get started!

    For those unfamiliar, the family of Tuts+ sites runs a premium membership service. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from Nettuts+, Psdtuts+, Aetuts+, Audiotuts+, Vectortuts+, and CgTuts+ For the price of a pizza, you’ll learn from some of the best minds in the business. Become a Premium member to read this tutorial, as well as hundreds of other advanced tutorials and screencasts.


  • Permalink for 'How to Query Web Services with a Build Script'

    How to Query Web Services with a Build Script

    Posted: August 12th, 2011, 8:55am MDT by Jeffrey Way

    Do you hate that your favorite web service can’t be used in your build scripts? Well, are you sure that’s the case? I’ll show you how to use a popular tool, Phing – which is essentially a port of the popular Apache Ant for PHP – to query the Nettuts+ Prefixr API in today’s quick tip.

    Choose 720p for the clearest picture.
    Subscribe to our YouTube and Blip.tv channels to watch more screencasts. Final Sample Phing Project
    <?xml version="1.0"?>
    
    <project name="demo" default="prefixr">
    	<property name="css.path" value="css/style.css" />
    	<target name="prefixr">
    		<echo msg="Updating your stylesheet" />
    		<loadfile property="css.min" file="${css.path}" />
    		<exec command="curl -sSd css='${css.min}' [prefixr.com] > ${css.path}" />
    	</target>
    
    </project>
    
    Conclusion

    The more I use Phing, the more I realize just how powerful it is. While many prefer Apache Ant for its portability, with Phing, I can use my existing PHP knowledge to create any new tasks or filters that I require. That’s incredibly powerful and convenient. What’s your build tool of choice?


  • Permalink for 'Cross-Browser CSS in Seconds with Prefixr'

    Cross-Browser CSS in Seconds with Prefixr

    Posted: August 3rd, 2011, 8:27am MDT by Jeffrey Way

    A couple weeks ago, as I began to manually update my stylesheet with all of the various browser prefixes for the new CSS3 properties, I thought to myself, “This is such a waste of time. Surely, there’s an easier way.

    Video Overview

    Tools like Compass, or even a TextMate bundle are tremendously helpful – I use them often, actually. But, for many projects, they aren’t available. As a result, we’re left in the position of having to copy and paste over, and over…and over.

    Introducing Prefixr.com (Alpha) Prefixr.com

    I built Prefixr to do all this tedious work for me. Simply paste in your stylesheet, press Prefixize (or hit Control + Enter), and Prefixr will filter through the applicable CSS3 properties and dynamically update them.

    Can’t remember if Opera provides a prefixed version of, say, the transition property (o-transition)? Don’t worry about it; that’s already coded into Prefixr!

    With Prefixr, you only code your stylesheets using the official W3C-recommended markup. When ready for deployment, run the stylesheet through Prefixr, and be done with it!

    Use the API

    Even better than visiting Prefixr.com is using its API from directly within your favorite code editor. Many editors, like TextMate, offer the ability to execute shell scripts. To automatically update your stylesheet in TextMate, create a new command, and paste in:

    curl -sSd "css=$TM_SELECTED_TEXT" " [prefixr.com] 
    TextMate Screenshot

    Now, select your stylesheet, and type the shortcut that you assigned. It will then be filtered through Prefixr, and dynamically updated. (See video above for more details.)

    Squash Those Bugs

    This is officially an Alpha release, which means that there are still some bugs to squash. All the kinks should be ironed out within this next week. If you find any yourself, there’s a Feedback button on the left-hand side of Prefixr.com that you can use to notify me.

    I hope this tool will be of help to you! Be sure to bookmark it!


  • Permalink for 'Essential TextMate Shortcuts, Tips and Techniques'

    Essential TextMate Shortcuts, Tips and Techniques

    Posted: July 31st, 2011, 9:07pm MDT by Jeffrey Way

    Even after six years, TextMate is still considered by many to be the best code editor available for Mac. The reason why is simple: it’s incredibly powerful, and offers features that even the newest editors don’t yet offer. Add a robust plugin/bundle community on top of it, and you get one heck of a code editor.

    I’ll show you some of my favorite shortcuts and tricks today.

    1 – Vertically Select Text
    Option + Drag

    If you hold down the Option key, and drag the mouse, you’ll vertically select text. This can be particularly helpful when you need to update a block of text.

    For example, let’s say we decide to remove the extra unnecessary var keywords from a bit of JavaScript? With vertical selection, this takes only a second.

    Vertical Text Select 2 – Alignment
     Option + Command + ]

    Many developers prefer to line up the symbols within arrays and objects. For example, rather than…

    var kimberly = 'valley girl',
        omg = 'oh my god!',
        bieber = 'my home boy';
    

    …many prefer:

    var kimberly = 'valley girl',
        omg      = 'oh my god!',
        bieber   = 'my home boy';
    

    This certainly makes for more readable code. If you’ve been lining up the equal signs manually, TextMate automates the process. Place the cursor on one of the related lines, press Option + Command + ], and TextMate will take care of the rest.

    3 – Incremental Search
    Control + 

    While the standard “popup” Command + f search functionality works, it’s decidedly slow. If you need to quickly search for a piece of text within the current page, use Control + s instead to perform incremental search.

    A tiny textbox will pop up at the bottom of the screen. Once you’ve added your search query, press enter, and you’ll instantly be transported to the next occurrence of that sequence on the page. To continue searching, again, press Control + s and Control + Shift + s to continue forward and backward, respectively.

    Incremental Search 4 – Set Bookmarks
    Command + F2 

    One of my favorite features in Vim is the ability to create “bookmarks” in your projects. This then allows you to immediately return to that line of code with a simple keystroke.

    TextMate offers this functionality as well. To star, or bookmark a line of code, place the cursor on that line, and type Command + F2.

    Bookmark Lines

    To return to this line of code (for instance, after scrolling up the page to find a particular variable name), type F2. If you have multiple starred lines, each time you press F2, you’ll be taken to the next applicable location.

    5 – Save Time with Macros
    Option + Command + m

    Let’s imagine that there’s a sequence of actions you find yourself performing often. For example, what if you find – like I have – that you frequently change the entire contents of an HTML tag. Vim offers the ever convenient, cit command (change inner tag).

    If you have the Zen Coding bundle installed, you can type Command + D to achieve the same effect. However, if you find that you often forget this shortcut, you can always record macros that will repeat any sequence of events as many times as your require.

    To begin a macro, type Option + Command + M; you’ll see a red recording circle in the lower right portion of the editor. At this point, TextMate is now listening to every action you perform. In our simple example, we only need to type Command + D (balance tag), and then Delete to remove the text.

    To conclude your recording, type the same sequence again: Option + Command + M. You may now repeat this sequence whenever you wish by typing Shift + Command + M.

    Note that, when you create a macro in this way, it’s meant to be a temporary solution. Once you create a new macro, or restart the editor, you will lose you recording. For a more permanent solution, you should following #6 in this list!

    6 – Create Permanent Macros
    Control + Command + m

    More often than not, you’ll need to access a variety of macros each day. You can record permanent macros in the same way that you did in #5 of this list. Once finished recording, type Control + Command + M to save the macro.

    Once you do, a dialog box will pop up, where you can then assign a custom activation key sequence for future retrieval.

    Permanent Macros

    I often find myself typing:

    echo '<pre>';
    print_r($variable);
    echo '</pre>';
    

    Let’s create a custom macro to do the work for us. We begin by creating a macro, as outlined in #5. This macro will assume that our variable is stored within the clipboard. Type the snippet of code above manually as you normally would. When you get to print_r(), press Command + v to paste in the contents of the clipboard. Once finished, press Option + Command + m to conclude the macro.

    Next, press Control + Command + m to save your macro; assign a tab trigger of debug, and you’re finished!

    From now on, to print_r an array or object, simply copy the variable name to your clipboard, and type debug + TAB.

    7 – Clipboard History
    Control + Shift + Command + v

    Many aren’t aware that TextMate has built-in clipboard history.

    “By pressing ⌃⌥⌘V, you will see the list of all previous clippings and can pick the one you want to paste using arrow keys. Use return to insert it and escape to dismiss the list. If you dismiss the list, the currently selected clipping will be what gets pasted the next time you use the paste function.”

    Clipboard History

    This is an incredibly useful feature that you’ll find yourself using constantly!

    8 – Execute Shell Scripts

    In addition to simple snippets, TextMate can also execute shell scripts. This means that all of the various web services are available for usage!

    We’ll use my Prefixr service as an example. It allows you to automatically update a stylesheet to include the various prefix’ized versions of the new CSS3 properties. That way, you can code your stylesheets using the official W3C-recommended versions of each property, and Prefixr will fix in the missing pieces.

    To hook into Prefixr’s [HTTP-based] API, create a new command in TextMate.

    Control + Shift + Command + B

    Next, add a new Command, and paste in the following shell script.

    curl -sSd "css=$TM_SELECTED_TEXT" " [prefixr.com] 

    shell script

    This instructs TextMate to run a shell script that performs a curl request to Prefixr.com. In the querystring, it passes the contents of what the TextMate user has selected with his mouse. That content is automatically represented, via the $TM_SELECTED_TEXT environment variable.

    Lastly, assign a keyboard shortcut to execute this command, and you’re done! To use it, select your entire stylesheet (or a single CSS3 property), and type the shortcut that you specified. Your code will immediately be updated accordingly.

    /* Before... */
    #content {
     border-radius: 5px;
     box-shadow: 30px;
    }
    
    /* After... */
    #content {
     -webkit-border-radius: 5px;
    -moz-border-radius: 5px;
    -o-border-radius: 5px;
    -ms-border-radius: 5px;
    -khtml-border-radius: 5px;
    border-radius: 5px;
    
    -webkit-box-shadow: 30px;
    -moz-box-shadow: 30px;
    box-shadow: 30px;
    }
    

    Pretty nifty, ay?

    9 – Auto-complete
    Escape

    Most IDEs offer the ability to autocomplete code – like method calls and variable references – typically by typing Control + Space. TextMate offers a similar feature, but via the Escape key instead. The key choice is a bit odd, but, of course, you can always map this to a different shortcut if you prefer. Simply type part of a variable or method name, press Escape, and TextMate will attempt to complete the word for you.

    If you’d prefer project-wide autocompletion, you can also use Command + ;.

    10 – Turbo-Charge the Editor

    Ciarán Walsh, a few years ago, created Project Plus, which enhances TextMate in a number of ways – the most noticeable being that it replaces the often criticized elastic sidebar with a more traditional one.

    Project Plus

    It also offers excellent, status badges to keep track of – for Git purposes – which files have changed since last being committed.

    Git Changed Git Changed 11 – Switch the Page Language
    Shift + Control + Option + {First-letter-of-language-choice}

    Dependent upon which language you specify for a page (set automatically by default), you’ll have access to different syntax highlighting and commands.

    Chances are, you’ll find yourself updating this often. It can be done manually by clicking the L button at the bottom of the editor.

    Language Selection

    This is a drag though. You can speed things up by typing Shift + Control + Option + {First-letter-of-language-choice}. For instance, if I want to change the page language to CSS, I’d type Shift + Control + Option + C.

    12 – Download Custom Bundles

    You’re certainly not limited to the dozen or so bundles that come preinstalled with TextMate. There’s a hugely robust community; you can download bundles and extensions for just about any language imaginable. A quick search on GitHub will return hundreds of results.

    Download Nettuts’ CSS3 TextMate bundle.

    CSS3 Bundle 13 – Search for a Command
    Control + Command + T

    There’s no denying it: it’s really difficult to remember all of these various commands. Rather than falling back to using the mouse and menu selections, instead type Control + Command + T. This will bring up a popup box, where you can then search for your desired command or snippet.

    Search 14 – Full Screen Mode in Lion

    Now that Lion is officially available to the public, you can upgrade TextMate to provide full screen support, using this plugin.

    15 – Speedy File Opening
    Command + T

    If you’re the type who requires lightning fast file switching, TextMate provides a built-in utility for opening files. Press Command + T to activate it.

    File Open

    However, if you’d prefer something a bit more robust and fuzzy, I highly recommend looking into PeepOpen, which works in a variety of editors. In addition to TextMate, I also use it in Vim.

    ” Search on both paths and filenames, and easily open the file in your text editor with a single keypress. Useful metadata helps you quickly choose the file you’re looking for.”

    File Open 16 – FTP Access

    An advantage that Espresso and Coda have over TextMate is that they offer built-in FTP access. This makes the process of editing files on your server as easy as possible. While TextMate doesn’t have a native solution to this problem, most Mac developers also use Panic’s popular Transmit app.

    Transmit

    We can use these two apps in tandem to edit files on our servers. Transmit offers the ability to mount a directory on your computer.

    Transmit mount feature Transmit mount feature

    With your server directory mounted, you can now open the directory from within TextMate. Each time you save a file, it will automatically be updated on your server as well. An elegant solution to a common gripe!

    That’s All for Now!

    I’ve barely scratched the surface of TextMate’s power. What are your favorite shortcuts and tricks? Let me know in the comments, and I just might update this article with your tip!

    More TextMate Articles from Nettuts+


  • Permalink for 'JavaScript Enlightenment: Now Available'

    JavaScript Enlightenment: Now Available

    Posted: July 27th, 2011, 2:24pm MDT by Jeffrey Way

    I’m pleased to help promote the follow-up to Cody Lindley‘s fantastic jQuery Enlightenment eBook, appropriately titled, JavaScript Enlightenment. Building upon his previous book, this newest release focuses exclusively on JavaScript objects, and will assist you in transitioning from a library user, to a full-fledged JavaScript developer!

    JavaScript Enlightenment Need a Sample

    If you need a sampling of the type of content the book offers, be sure to check out the excerpt on Nettuts+, which focuses on the ever-confusing this keyword.

    So What’s This Book About?

    ” This book is not about JavaScript design patterns or implementing an object-oriented paradigm with JavaScript code. It was not written to distinguish the good features of the JavaScript language from the bad. It is not meant to be a complete reference guide. It is not targeted at people new to programming or those completely new to JavaScript. Nor is this a cookbook of JavaScript recipes. Those books have been written.

    It was my intention to write a book to give the reader an accurate JavaScript worldview through an examination of native JavaScript objects and supporting nuances: complex values, primitive values, scope, inheritance, the head object, etc. I intend this book to be a short and digestible summary of the ECMA-262, Edition 3 specification, focused on the nature of objects in JavaScript.

    If you are a designer or developer who has only used JavaScript under the mantle of libraries (such as jQuery, Prototype, etc), it is my hope that the material in this book will transform you from a JavaScript library user into a JavaScript developer.”

    Who is Cody Lindley?

    Cody Lindley is a client-side engineer (aka front-end developer) and recovering Flash developer. He has an extensive background working professionally (11+ years) with HTML, CSS, JavaScript, Flash, and client-side performance techniques as it pertains to web development. If he is not wielding client-side code he is likely toying with interface/interaction design or authoring material and speaking at various conferences. When not sitting in front of a computer, it’s a sure bet he is hanging out with his wife & kids in Boise, Idaho, training for triathlons, skiing, mountain biking, road biking, alpine climbing, reading, watching movies, or debating the rational evidence for a Christian worldview. Currently he is working for memolane.com as a Lead Client-side Engineer.

    Buy the Book! JavaScript Enlightenment

    If you’re hoping to take your JavaScript skills to the next level, absolutely pick this one up without a second thought. There’s nobody more qualified to bring you to the next level than Cody. A huge thumbs up from the Nettuts+ editor.


  • Permalink for 'Quick Tip: How to Add Syntax Highlighting to Any Project'

    Quick Tip: How to Add Syntax Highlighting to Any Project

    Posted: July 26th, 2011, 5:17pm MDT by Jeffrey Way

    In this lesson, we’ll use a JavaScript based syntax highlighter to quickly add a syntax highlighting functionality to any web project — even on a simple HTML page!

    Step 1 — Download the Source Code

    You can download the syntax highlighter source files here.

    Step 2 — Drag the src Directory into your Project

    I generally rename this folder to highlighter. Don’t delete anything within here, unless you don’t anticipate using some of the language specific JavaScript files.

    Step 3 — Import the Necessary Files

    Within your HTML file (or whichever page is responsible for displaying your view), import both the prettify.css and prettify.js files.

    <!DOCTYPE html>
    
    <html lang="en">
    <head>
       <meta charset="utf&mdash;8">
       <title>untitled</title>
       <link rel="stylesheet" href="highlighter/prettify.css" />
    </head>
    <body>
    
    <script src="highlighter/prettify.js"></script>
    
    </body>
    </html>
    

    Notice how we’ve placed our script at the bottom of the page, just before the closing body tag. This is always a smart move, as it improves performance.

    Next, we need something to work with! The syntax highlighter will search for either a pre or code element that has a class of prettyprint. Let’s add that now.

    <pre class="prettyprint">
    (function() {
       var jsSyntaxHighlighting = 'rocks';
    })();
    </pre>
    
    Step 4 — Calling the prettyPrint() Function

    The last step is to execute the prettyPrint() function. We can place this bit of code at the bottom of the page as well.

    <!DOCTYPE html>
    
    <html lang="en">
    <head>
       <meta charset="utf-8">
       <title>untitled</title>
       <link rel="stylesheet" href="highlighter/prettify.css" />
    </head>
    <body>
    
    <pre class="prettyprint">
    (function() {
       var jsSyntaxHighlighting = 'rocks';
    })();
    </pre>
    <script src="highlighter/prettify.js"></script>
    <script>prettyPrint();</script>
    </body>
    </html>
    

    If we now view the page in the browser…

    final product

    Well that was easy! But, as a final bonus step, what if we want to change the highlighter theme? In that case, it all comes down to editing the stylesheet how you see fit. Even better, there are a handful of stylesheets in the theme gallery that you’re free to use. I personally like the Desert theme. To apply it, copy the CSS from the link above, create a new stylesheet in your project, and paste the CSS into it. Next, update the stylesheet include from within the head section of your document.

    <head>
       <meta charset="utf&mdash;8">
       <title>untitled</title>
       <link rel="stylesheet" href="highlighter/dessert.css" />
    </head>
    
    Desert Theme Applied

    Seriously — can it get any simpler than that?