<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:series="http://unfoldingneurons.com/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>Nettuts+</title> <link>http://net.tutsplus.com</link> <description>Web Development &amp; Design Tutorials</description> <lastBuildDate>Fri, 24 May 2013 17:30:15 +0000</lastBuildDate> <language /> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.5</generator> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/nettuts" /><feedburner:info uri="nettuts" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><image><link>http://nettuts.com</link><url>http://envato.s3.amazonaws.com/rss_images/nettuts.jpg</url><title>NETTUTS</title></image><feedburner:emailServiceId>nettuts</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><item><title>Win a Ticket to Our New Tuts+ Live Workshop</title><link>http://feedproxy.google.com/~r/nettuts/~3/yxNzqpMgCJ8/</link> <comments>http://net.tutsplus.com/articles/news/win-a-ticket-to-our-new-tuts-live-workshop/#comments</comments> <pubDate>Fri, 24 May 2013 17:30:15 +0000</pubDate> <dc:creator>Joel Bankhead</dc:creator> <category><![CDATA[News]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31864</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31864&amp;c=714551794' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31864&amp;c=714551794' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;&lt;strong&gt;We have 5 tickets to give away for our newest Tuts+ Live Workshop, all you have to do is &lt;a
href="http://eepurl.com/qnEP5"&gt;subscribe to our newsletter&lt;/a&gt;. Be quick though, this giveaway ends on Monday!&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;We have a superb new Workshop, &lt;a
href="http://workshops.tutsplus.com/plugin-development.html?utm_source=nettuts&amp;#038;utm_medium=giveawaypost&amp;#038;utm_campaign=pluginw"&gt;Introduction to WordPress Plugin Development&lt;/a&gt;, starting in a week. This is your chance to win a free ticket!&lt;/p&gt;&lt;p&gt;Simply &lt;a
href="http://eepurl.com/qnEP5"&gt;subscribe to the Tuts+ Live Workshops newsletter&lt;/a&gt; and we’ll pick the winners on Monday 27th. Read on to find out more about the Workshop and for more details about the giveaway!&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31864"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Introduction to WordPress Plugin Development&lt;/h2&gt;&lt;p&gt;Our newest Tuts+ Live Workshop, Introduction to WordPress Plugin Development, teaches you everything that you need to know to start developing WordPress plugins; from setting up a local development environment, all the way through to building a WordPress plugin that&amp;#8217;s ready for release into the WordPress Plugin Repository.&lt;/p&gt;&lt;p&gt;It&amp;#8217;s led by Instructor Tom McFarlin, a self-employed WordPress developer who divides his time between running his own WordPress development shop, building plugins for WordPress, blogging every day about software development in the context of WordPress, and working for 8BIT (the team responsible for Standard Theme and WP Daily).&lt;/p&gt;&lt;p&gt;Each weekly workshop will last one hour, running over a five week period. You&amp;#8217;ll have the opportunity to follow along with Tom, ask questions live during the workshop, and complete a weekly homework assignment. Not able to make it to the live recording? No problem! All of the workshop recordings will be made available online the day after the live workshop.&lt;/p&gt;&lt;p&gt;&lt;a
href="http://workshops.tutsplus.com/plugin-development.html?utm_source=nettuts&amp;#038;utm_medium=giveawaypost&amp;#038;utm_campaign=pluginw"&gt;Learn more about Introduction to WordPress Plugin Development&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;iframe
width="640" height="360" src="http://www.youtube.com/embed/QErsaJMdmCc?rel=0" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Subscribe and Win a Ticket!&lt;/h2&gt;&lt;p&gt;We have 5 tickets to give away and will be choosing the winners from everyone who has subscribed to the Tuts+ Live Workshops newsletter, so no worries if you’ve already signed up. We’ll also reimburse any winners who have already paid for their ticket.&lt;/p&gt;&lt;p&gt;To enter simply &lt;a
href="http://eepurl.com/qnEP5"&gt;subscribe to the Tuts+ Live Workshops newsletter&lt;/a&gt; and stay informed on upcoming workshops!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=yxNzqpMgCJ8:b9ccTY7PJRg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=yxNzqpMgCJ8:b9ccTY7PJRg:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=yxNzqpMgCJ8:b9ccTY7PJRg:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=yxNzqpMgCJ8:b9ccTY7PJRg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=yxNzqpMgCJ8:b9ccTY7PJRg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=yxNzqpMgCJ8:b9ccTY7PJRg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=yxNzqpMgCJ8:b9ccTY7PJRg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=yxNzqpMgCJ8:b9ccTY7PJRg:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/yxNzqpMgCJ8" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/articles/news/win-a-ticket-to-our-new-tuts-live-workshop/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://net.tutsplus.com/articles/news/win-a-ticket-to-our-new-tuts-live-workshop/</feedburner:origLink></item> <item><title>Cargo-Culting in JavaScript</title><link>http://feedproxy.google.com/~r/nettuts/~3/i3fMBPBrtbM/</link> <comments>http://net.tutsplus.com/tutorials/javascript-ajax/cargo-culting-in-javascript/#comments</comments> <pubDate>Fri, 24 May 2013 15:04:57 +0000</pubDate> <dc:creator>James Padolsey</dc:creator> <category><![CDATA[JavaScript & AJAX]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31879</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31879&amp;c=1398725923' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31879&amp;c=1398725923' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;Cargo-cult programming is what a programmer does when he or she doesn&amp;#39;t know a particular language or paradigm well enough, and so ends up writing redundant and possibly harmful code. It rears its head quite often in the land of JavaScript. In this article, I explore the concept of cargo-cult programming and places to watch out for it in JavaScript.&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31879"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote
class="pullquote"&gt;&lt;p&gt; Dogmatic rules surface and spread, until they are considered the norm.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Cargo-culting is sometimes defined as &amp;quot;&lt;a
href="http://www.softpanorama.org/Skeptics/IT_skeptic/cargo_cult_programming.shtml"&gt;the extreme adherence to the form instead of content&lt;/a&gt;.&amp;quot; The form, in programming, being the syntax, paradigms, styles and patterns that we employ. The content being the abstract thing that you are seeking to represent through your code &amp;mdash; the very substance of your program. A person with lacking understanding in an area is likely to copy the form of others without truly understanding, and thus their content &amp;mdash; their program &amp;mdash; can suffer.&lt;/p&gt;&lt;p&gt;Cargo-culting is curiously common in JavaScript, probably because of the general low barrier to entry in the front-end development world. You can whip up an HTML page with a bit of JavaScript in seconds. As a result, there are many people who become sufficiently proficient in these technologies to feel comfortable creating and imposing rules on themselves and others. Eventually, other newcomers copy these rules. Dogmatic rules surface and spread, until they are considered the norm:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Always use strict equality operators&lt;/li&gt;&lt;li&gt;Never use eval&lt;/li&gt;&lt;li&gt;Always use a single var declaration per scope&lt;/li&gt;&lt;li&gt;Always use an IIFE &amp;#8211; it &amp;#8220;protects&amp;#8221; you&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;A rule continues to spread until a programmer is only using a given technique because of its popularity, instead of considering each specific use-case independently.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;JavaScript Abuzz with Semi-colons&lt;/h2&gt;&lt;p&gt;If you&amp;#39;ve had the opportunity to witness the witty banter and rhetoric of the software developer over the years, you will have spotted a tendency to discuss seemingly tiny things at great lengths. Things like the semi-colon, the comma, white-space or the curly brace.&lt;/p&gt;&lt;p&gt;Syntax like semi-colons or white-space may seem to purely be elements of form, not of content. But many of these subtle syntax rules can have significant effects in JavaScript. If you don&amp;#39;t understand the &amp;#39;form&amp;#39; then you cannot begin to understand the &amp;#39;content&amp;#39;.&lt;/p&gt;&lt;p&gt;So in this article, we will identify what areas of form in JavaScript are frequently cargo-culted off of &amp;mdash; that is, copied without understanding.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt; &lt;img
alt="How JavaScript can seem" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/js_iceberg.jpg" border="0" /&gt;&lt;/p&gt; &lt;figcaption&gt;&lt;em&gt;How JavaScript can seem&amp;#8230;&lt;/em&gt; an image from Angus Croll&amp;#8217;s &amp;quot;&lt;a
href="https://speakerdeck.com/anguscroll/the-politics-of-javascript"&gt;The Politics Of JavaScript&lt;/a&gt;&amp;quot; presentation&lt;/figcaption&gt; &lt;/figure&gt;&lt;hr
/&gt;&lt;h2&gt;Undefined&lt;/h2&gt;&lt;p&gt;Angus Croll, in a recent presentation, titled &amp;quot;&lt;a
href="https://speakerdeck.com/anguscroll/the-politics-of-javascript"&gt;The Politics Of JavaScript&lt;/a&gt;&amp;quot;, highlighted one of the most common pieces of JS dogma that people cargo-cult off of:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;if (typeof myObject.foo === 'undefined') {...}
&lt;/pre&gt;&lt;p&gt;Most of the time, doing such a long-winded check for &lt;code&gt;undefined&lt;/code&gt; is pointless. The technique became common because people were copying other people, not because of it&amp;#39;s actual value.&lt;/p&gt;&lt;p&gt;Of course, there are times when:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
typeof x === 'undefined'
&lt;/pre&gt;&lt;p&gt;&amp;#8230; is preferable to:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;x === undefined
&lt;/pre&gt;&lt;p&gt;But, equally, there are times when the latter is preferred. A quick overview of the options:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
// Determine if `x` is undefined:
x === undefined
typeof x == 'undefined'
typeof x === 'undefined'
x === void 0

// Determine if `x` is undefined OR null:
x == null
x == undefined
&lt;/pre&gt;&lt;p&gt;People started using the &lt;code&gt;typeof&lt;/code&gt; approach because they were protecting themselves against:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A potentially undeclared variable (&lt;em&gt;non-typeof approaches would throw TypeErrors&lt;/em&gt;)&lt;/li&gt;&lt;li&gt;Someone overwrote undefined globally or in a parent scope. Some environments allow you to overwrite &lt;code&gt;undefined&lt;/code&gt; to something like &lt;code&gt;true&lt;/code&gt;. You have to ask yourself: &amp;#8220;&lt;em&gt;Is it likely that someone overwrote undefined, and should my script have to pander to such silliness?&lt;/em&gt;&amp;#8220;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;But most of the time they&amp;#39;re protecting themselves from having to worry. It&amp;#39;s a catch-all avoidance of having to know the details. Knowing the details can help you though. Every character of your code should exist with a purpose in mind.&lt;/p&gt;&lt;p&gt;The only time that you should need to use a &lt;code&gt;typeof&lt;/code&gt; check for &lt;code&gt;undefined&lt;/code&gt; is when you are checking for a variable that may not have been declared, e.g. checking for jQuery in the global scope:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
if (typeof jQuery != 'undefined') {
    // ... Use jQuery
}
&lt;/pre&gt;&lt;p&gt;The thing is, if jQuery &lt;em&gt;does&lt;/em&gt; exist, then we can be sure that it&amp;#39;s an object &amp;#8211; a &amp;quot;&lt;a
href="http://james.padolsey.com/javascript/truthy-falsey/"&gt;truthy&lt;/a&gt;&amp;quot; thing. So this would be sufficient:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
// or:
if (window.jQuery) {

}
&lt;/pre&gt;&lt;hr
/&gt;&lt;h2&gt;The Great Strict/non-strict Debate&lt;/h2&gt;&lt;p&gt;Let&amp;#39;s take something very common and generally considered good advice, solely using strict-equality:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
a === b
&lt;/pre&gt;&lt;p&gt;Strict-equality is said to be good because it avoids ambiguity. It checks both the value and the type, meaning that we don&amp;#39;t have to worry about implicit coercion. With non-strict equality, we do have to worry about it though:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
1 == 1    // true &amp;amp;mdash; okay, that's good
1 == &amp;quot;1&amp;quot;  // true &amp;amp;mdash; hmm
1 == [1]  // true &amp;amp;mdash; wat!?
&lt;/pre&gt;&lt;p&gt;So it would seem sensible advice to entirely avoid non-strict equality, right? Actually, no. There are many situations where strict-equality creates large amounts of redundancy, and non-strict equality is preferable.&lt;/p&gt;&lt;p&gt;When you know, with 100% certainty, that the types of both operands are the same, you can avoid the need for strict-equality. For example, I always know that the &lt;code&gt;typeof&lt;/code&gt; operator returns a string, and my right-hand operand is also a string (e.g. &lt;code&gt;&amp;quot;number&amp;quot;&lt;/code&gt;):&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
// With strict-equals
typeof x === 'number'

// With non-strict-equals:
typeof x == 'number'
&lt;/pre&gt;&lt;p&gt;They&amp;#39;re both effectively identical. I am not necessarily suggesting that we abandon strict-equals in this case &amp;mdash; I am suggesting that we remain aware of what we&amp;#39;re doing so that we can make the best choices given each situation.&lt;/p&gt;&lt;p&gt;Another quite useful example is when you want to know if a value is either &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;. With strict equality, you might do this:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
if (value === undefined || value === null) {
    // ...
}
&lt;/pre&gt;&lt;p&gt;With non-strict equality, it&amp;#39;s far simpler:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
if (value == null) {
    // ...
}
&lt;/pre&gt;&lt;p&gt;There is no catch here &amp;mdash; it is doing exactly what we want, only, arguably, less visibly. But, if we know the language, then what&amp;#39;s the problem? It&amp;#39;s right there &lt;a
href="http://es5.github.io/#x11.9.3"&gt;in the spec&lt;/a&gt;:&lt;/p&gt;&lt;p&gt;The comparison &lt;code&gt;x == y&lt;/code&gt;, where &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt; are values, produces &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;. Such a comparison is performed as follows:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;If x is null and y is undefined, return true.&lt;li&gt;If x is undefined and y is null, return true.&lt;/p&gt;&lt;/ul&gt;&lt;p&gt;If you&amp;#39;re writing JavaScript with the intention of it being read, if at all, by people that know JavaScript, then I would argue that you shouldn&amp;#39;t feel bad taking advantage of implicit language rules, like this.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;&lt;code&gt;hasOwnProperty&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;hasOwnProperty&lt;/code&gt; method is used to determine whether a property is directly owned by an object. Is it commonly found in &lt;code&gt;for..in&lt;/code&gt; loops to ensure that you only mess with direct properties and not inherited properties.&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
for (var i in object) {
    if (object.hasOwnProperty(i)) {
        // We can do stuff with `object[i]`
    }
}
&lt;/pre&gt;&lt;p&gt;It&amp;#8217;s important to note that the &lt;code&gt;for-in&lt;/code&gt; statement will only loop through enumarable properties. Native inherited methods, for example, are not enumerable and so you don&amp;#39;t need to worry about them anyway.&lt;/p&gt;&lt;p&gt;The &lt;code&gt;hasOwnProperty&lt;/code&gt; check is specifically preventing you from touching properties that you or some third-party script has defined, i.e. when your object&amp;#39;s prototype has enumerable properties.&lt;/p&gt;&lt;p&gt;If you know that your object&amp;#39;s prototype (&lt;em&gt;or its prototype&amp;#8217;s prototype&lt;/em&gt; etc.) doesn&amp;#39;t have any enumerable properties, then &lt;em&gt;you don&amp;#39;t have to worry&lt;/em&gt; about using &lt;code&gt;hasOwnProperty&lt;/code&gt; in your &lt;code&gt;for-in&lt;/code&gt; loops. And, if your object is initialized, via ES5&amp;#39;s &lt;code&gt;Object.create(null)&lt;/code&gt;, then you won&amp;#39;t even be able to call &lt;code&gt;hasOwnProperty&lt;/code&gt; directly on the object (&lt;em&gt;no prototype means no inherited native methods&lt;/em&gt;). This means that using &lt;code&gt;hasOwnProperty&lt;/code&gt; by default in all of your &lt;code&gt;for-in&lt;/code&gt; loops may actually break sometimes.&lt;/p&gt;&lt;p&gt;One potential solution for objects with &lt;code&gt;null&lt;/code&gt; prototypes is to use a saved reference to &lt;code&gt;hasOwnProperty&lt;/code&gt;, like so:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var hasOwnProperty = Object.prototype.hasOwnProperty;

// Later in your code:
for (var i in someObject) {
    if (hasOwnProperty.call(someObject, i)) {
        // ...
    }
}
&lt;/pre&gt;&lt;p&gt;That will work even if the object has no prototype (in the case of &lt;code&gt;Object.create(null)&lt;/code&gt;). But, of course, we should only do this in the first place if we know we need it. If you&amp;#39;re writing a third-party script for a &amp;quot;hostile&amp;quot; environment, then yes, definitely check for enumerable inherited properties. Otherwise, it may not be necessary all the time.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; IE9 and Safari 2.0 complicate the matter further when you&amp;#39;re trying to identify enumerable properties that are already defined as non-enumerable. It&amp;#39;s worth checking out &lt;a
href="https://github.com/bestiejs/spotlight.js/blob/7077cdeda829dd0965c911365e33e406a24a41aa/spotlight.js#L74-183"&gt;a truly cross-browser forOwn loop implementation&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;To conclude: your use of &lt;code&gt;hasOwnProperty&lt;/code&gt; should depend on the object being looped over. It depends on what assumptions you can safely make. Blindly protecting yourself using the &lt;code&gt;hasOwnProperty&lt;/code&gt; will not suffice in all cases. Be wary of cross-browser differences too.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Over-Parenthesising&lt;/h2&gt;&lt;p&gt;Another common redundancy that creeps into JS code is the parenthesis. Within expressions, it is used to force specific grouping of sub-expressions. Without them, you are at the mercy of &lt;a
href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence#Table"&gt;operator precedences and associativities&lt;/a&gt;. For example:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
A &amp;amp;&amp;amp; B || C
A &amp;amp;&amp;amp; (B || C)
(A &amp;amp;&amp;amp; B) || C
&lt;/pre&gt;&lt;p&gt;One of those is not like the other. The parentheses force a specific grouping, and many people prefer the extra clarity. In this case, the logical AND operator has a higher precedence than the logical OR operator, meaning that it is the first and last lines that are equivelant. The second line is an entirely different logical operation.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Higher precedence means that it will occur before other operations in a series of operations.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;To avoid this complexity, developers frequently opt for a &amp;quot;parentheses policy&amp;quot; &amp;mdash; where you keep adding parentheses until it is abundantly clear which operations are occurring, both for you and potential readers of the code. It can be argued that this verbosity ends up making things less clear though.&lt;/p&gt;&lt;p&gt;It&amp;#8217;s tricky for a reader sometimes. One must consider that any given parentheses may have been added because:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It was needed to override default precedence/associativity&lt;/li&gt;&lt;li&gt;For no functional reason at all, just for &amp;quot;protection&amp;quot; or &amp;quot;clarity&amp;quot;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Take this example:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
A &amp;amp;&amp;amp; B ? doFoo() : doBaz()
&lt;/pre&gt;&lt;p&gt;Without knowledge of operator precedence rules, we can see two possible operations here:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
(A &amp;amp;&amp;amp; B) ? doFoo() : doBaz()
A &amp;amp;&amp;amp; (B ? doFoo() : doBaz())
&lt;/pre&gt;&lt;p&gt;In this case, it&amp;#39;s the logical AND that has the higher precedence, meaning that the equivalent parenthesised expression is:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
(A &amp;amp;&amp;amp; B) ? doFoo() : doBaz()
&lt;/pre&gt;&lt;p&gt;We should feel no obligation to add these parentheses in our code, though. It happens implicitly. Once we recognize that it happens implicitly, we are free to ignore it and focus on the program itself.&lt;/p&gt;&lt;p&gt;There are, of course, valid arguments to retain the parentheses where implicit grouping is unclear. This really comes down to you and what you&amp;#39;re comfortable with. I would, however, implore you to &lt;a
href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence#Table"&gt;learn the precedences&lt;/a&gt; and then you can be fully empowered to take the best route, dependent on the specific code you&amp;#39;re dealing with.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Object Keys&lt;/h2&gt;&lt;p&gt;It&amp;#39;s not rare to see redundant quotes in object literals:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var data = {
  'date': '2011-01-01',
  'id': 3243,
  'action': 'UPDATE',
  'related': { '1253': 2, '3411': 3 }
};
&lt;/pre&gt;&lt;p&gt;In addition to strings, JavaScript allows you to use valid identifier names and numbers as object literal keys, so the above could be re-written to:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var data = {
  date: '2011-01-01',
  id: 3243,
  action: 'UPDATE',
  related: { 1253: 2, 3411: 3 }
};
&lt;/pre&gt;&lt;p&gt;Sometimes, you may prefer the added consistency of being able to use quotes, especially if a field-name happens to be a reserved word in JavaScript (like &amp;#39;class&amp;#39; or &amp;#39;instanceof&amp;#39;). And that&amp;#39;s fine.&lt;/p&gt;&lt;p&gt;Using quotes is not a bad thing. But it is redundant. Knowing that you don&amp;#39;t have to use them is half the battle won. It is now your choice to do what you want.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Comma Placement&lt;/h2&gt;&lt;p&gt;There is a huge amount of subjective preference, when it comes to punctuation placement in programming. Most recently, the JavaScript world has been abuzz with rhetoric and discontent over the comma.&lt;/p&gt;&lt;p&gt;Initialising an object in traditionally idiomatic JavaScript looks like this:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var obj = {
    a: 1,
    b: 2,
    c: 3
};
&lt;/pre&gt;&lt;p&gt;There is an alternative approach, which has been gaining momentum though:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var obj = {
      a: 1
    , b: 2
    , c: 3 
};
&lt;/pre&gt;&lt;p&gt;The supposed benefit of placing the commas before each key-value pair (apart from the first) is that it means you only have to touch one line in order to remove a property. Using the traditional approach, you would need to remove &amp;quot;&lt;code&gt;c: 3&lt;/code&gt;&amp;quot; and then the trailing comma on the line above. But with the comma-first approach you&amp;#39;re able to just remove &amp;quot;&lt;code&gt;, c: 3&lt;/code&gt;&amp;quot;. Proponents claim this makes trailing commas less likely and also cleans up source-control diffs.&lt;/p&gt;&lt;p&gt;Opponents, however, say that this approach only achieves getting rid of the trailing-comma &amp;quot;problem&amp;quot; by introducing a new leading-comma problem. Try removing the first line and you&amp;#39;re left with a leading comma on the next line. This is actually considered a good thing by comma-first proponents, because a leading comma would immediately throw a SyntaxError. A trailing comma, however, throws nothing, except in IE6 and 7. So if the developer fails to test their JS in those versions of IE, then the trailing commas can often creep into production code, which is never good. A leading comma throws in all environments, so is less likely to be missed.&lt;/p&gt;&lt;p&gt;Of course, you might argue that this entire thing is moot. We should probably be using linters like &lt;a
href="http://www.jslint.com/"&gt;JSLint&lt;/a&gt; or the kinder &lt;a
href="http://www.jshint.com/"&gt;JSHint&lt;/a&gt;. Then we&amp;#39;re free to use the punctuation and whitespace placement that makes the most sense to us and our coworkers.&lt;/p&gt;&lt;p&gt;Let&amp;#39;s not even get started on the comma-first style in variable declarations..&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
var a = 1
  , b = 2
  , c = 3
  ;
&lt;/pre&gt;&lt;hr
/&gt;&lt;h2&gt;Thou Shalt Code for Psychopaths?&lt;/h2&gt;&lt;p&gt;We should endeavour to learn the languages we use to a good enough level that we&amp;#39;re able to avoid cargo-culting and over-protective catch-all coding techniques. And we should trust our coworkers and other developers to do the same.&lt;/p&gt;&lt;p&gt;We&amp;#8217;ve also discussed the abandonement of cruft in favor of taking advantage of a language&amp;#8217;s idiosyncracies and implicit rules. To some, this creates maintainability issues, especially if someone more junior in their acquisition of a given language approaches the code. For example, what if they don&amp;#8217;t know about JavaScript&amp;#8217;s weak vs. strict equality?&lt;/p&gt;&lt;p&gt;On the topic of maintainability, we&amp;#8217;re reminded &lt;a
href="http://c2.com/cgi/wiki?CodeForTheMaintainer"&gt;by this famous quote&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;I don&amp;#8217;t know if that is truly good advice. Even taken metaphorically, it suggests a distrust of the fictional maintainer&amp;#8217;s competency &amp;mdash; and the need to worry about their understanding above everything else. I would rather write code in the knowledge that it will be taken care of by people that know their stuff. So as a possible contradiction or even an addendum to that quote, I offer:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Always code as if the person who ends up maintaing your code is knowledgeable about the language and its constructs and is seeking to gain understanding of the problem domain through reading your code.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;While this may not always be true, we should seek for it be so. We should endeavour to ensure that people working on a specific technology have the sufficient understanding to do so. The learned cargo-culter says:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If I forever pander to a lower level of understanding in my code &amp;mdash; treading softly &amp;mdash; strictly abiding to conventions and style guides and things I see the &amp;#8220;experts&amp;#8221; do, then I am never able to advance my own understanding, nor take advantage of a language in all its weirdness and beauty. I am happily and blissfully settled in this world of rules and absolutes, but to move forward, I must exit this world and embrace higher understanding.&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=i3fMBPBrtbM:JoWiE7wYzX8:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=i3fMBPBrtbM:JoWiE7wYzX8:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=i3fMBPBrtbM:JoWiE7wYzX8:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=i3fMBPBrtbM:JoWiE7wYzX8:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=i3fMBPBrtbM:JoWiE7wYzX8:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=i3fMBPBrtbM:JoWiE7wYzX8:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=i3fMBPBrtbM:JoWiE7wYzX8:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=i3fMBPBrtbM:JoWiE7wYzX8:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/i3fMBPBrtbM" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/cargo-culting-in-javascript/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/javascript-ajax/cargo-culting-in-javascript/</feedburner:origLink></item> <item><title>Laravel 4: A Start at a RESTful API (Updated)</title><link>http://feedproxy.google.com/~r/nettuts/~3/iseZmkJPwRw/</link> <comments>http://net.tutsplus.com/tutorials/php/laravel-4-a-start-at-a-restful-api/#comments</comments> <pubDate>Wed, 22 May 2013 16:00:07 +0000</pubDate> <dc:creator>Chris Fidao</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[api]]></category> <category><![CDATA[laravel]]></category> <category><![CDATA[rest]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=29785</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=29785&amp;c=1562182474' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=29785&amp;c=1562182474' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;RESTful API&amp;#39;s are hard! There are a lot of aspects to designing and writing a successful one. For instance, some of the topics that you may find yourself handling include authentication, hypermedia/HATEOS, versioning, rate limits, and content negotiation. Rather than tackling all of these concepts, however, let&amp;#39;s instead focus on the basics of REST. We&amp;#39;ll make some JSON endpoints behind a basic authentication system, and learn a few Laravel 4 tricks in the process.&lt;/p&gt;&lt;p&gt;&lt;span
id="more-29785"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;The App&lt;/h2&gt;&lt;p&gt;Let&amp;#39;s build an API for a simple Read-It-Later app. Users will be able to create, read, update and delete URLs that they wish to read later.&lt;br
/&gt; Ready to dive in and get started?&lt;/p&gt;&lt;h3&gt;Install Laravel 4&lt;/h3&gt;&lt;p&gt;Create a new &lt;a
href="http://four.laravel.com/#install-laravel" title="install laravel"&gt;install of Laravel 4&lt;/a&gt;. If you&amp;#39;re handy with CLI, try this &lt;a
href="http://fideloper.com/laravel-4-uber-quick-start-with-auth-guide?utm_source=nettuts&amp;amp;utm_medium=article&amp;amp;utm_content=api&amp;amp;utm_campaign=guest_author" title="laravel quick start"&gt;quickstart guide&lt;/a&gt;. Otherwise, we have a &lt;a
href="http://net.tutsplus.com/tutorials/php/how-to-setup-laravel-4/" title="install laravel video"&gt;video tutorial here on Nettuts+&lt;/a&gt; that covers the process.&lt;/p&gt;&lt;p&gt;We&amp;#39;re going to first create an encryption key for secure password hashing. You can do this easily by running this command from your project root:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ php artisan key:generate
&lt;/pre&gt;&lt;p&gt;Alternatively, you can simple edit your &lt;code&gt;app/config/app.php&lt;/code&gt; encryption key:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;/*
|--------------------------------------------------------------------------
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, long string, otherwise these encrypted values will not
| be safe. Make sure to change it before deploying any application!
|
*/

'key' =&amp;gt; md5('this is one way to get an encryption key set'),
&lt;/pre&gt;&lt;h3&gt;Database&lt;/h3&gt;&lt;p&gt;Once you have a working install of Laravel 4, we can get started with the fun. We&amp;#39;ll begin by creating the app&amp;#39;s database.&lt;/p&gt;&lt;p&gt;This will only require two database tables:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;strong&gt;Users&lt;/strong&gt;, including a username and password&lt;/li&gt;&lt;li&gt;&lt;strong&gt;URLs&lt;/strong&gt;, including a url and description&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;We&amp;#39;ll use Laravel&amp;#39;s &lt;a
href="http://four.laravel.com/docs/migrations" title="create Laravel migrations"&gt;migrations&lt;/a&gt; to create and populate the database.&lt;/p&gt;&lt;h3&gt;Configure Your Database&lt;/h3&gt;&lt;p&gt;Edit &lt;code&gt;app/config/database.php&lt;/code&gt; and fill it with your database settings. Note: this means creating a database for this application to use. This article assumes a MySQL database.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;'connections' =&amp;gt; array(

    'mysql' =&amp;gt; array(
        'driver'    =&amp;gt; 'mysql',
        'host'      =&amp;gt; 'localhost',
        'database'  =&amp;gt; 'read_it_later',
        'username'  =&amp;gt; 'your_username',
        'password'  =&amp;gt; 'your_password',
        'charset'   =&amp;gt; 'utf8',
        'collation' =&amp;gt; 'utf8_unicode_ci',
        'prefix'    =&amp;gt; '',
    ),
),
&lt;/pre&gt;&lt;h3&gt;Create Migration Files&lt;/h3&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ php artisan migrate:make create_users_table --table=users --create
$ php artisan migrate:make create_urls_table --table=urls --create
&lt;/pre&gt;&lt;p&gt;These commands set up the basic migration scripts that we&amp;#39;ll be using to create the database tables. Our job now is to fill them with the correct table columns.&lt;/p&gt;&lt;p&gt;Edit &lt;code&gt;app/database/migrations/SOME_DATE_create_users_table.php&lt;/code&gt; and add to the &lt;code&gt;up()&lt;/code&gt; method:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;public function up()
{
    Schema::create('users', function(Blueprint $table)
    {
        $table-&amp;gt;increments('id');
        $table-&amp;gt;string('username')-&amp;gt;unique();
        $table-&amp;gt;string('password');
        $table-&amp;gt;timestamps();
    });
}
&lt;/pre&gt;&lt;p&gt;Above, we&amp;#39;re setting a username (which should be unique), a password, as well as the timestamps. Save that, and now edit &lt;code&gt;app/database/migrations/SOME_DATE_create_urls_table.php&lt;/code&gt;, and add to the &lt;code&gt;up()&lt;/code&gt; method:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;public function up()
{
    Schema::create('urls', function(Blueprint $table)
    {
        $table-&amp;gt;increments('id');
        $table-&amp;gt;integer('user_id');
        $table-&amp;gt;string('url');
        $table-&amp;gt;string('description');
        $table-&amp;gt;timestamps();
    });
}
&lt;/pre&gt;&lt;p&gt;The only important note in this snippet is that we&amp;#39;re creating a link between the &lt;code&gt;url&lt;/code&gt; and &lt;code&gt;users&lt;/code&gt; table, via the &lt;code&gt;user_id&lt;/code&gt; field.&lt;/p&gt;&lt;h3&gt;Add Sample Users&lt;/h3&gt;&lt;p&gt;We can use Laravel&amp;#39;s &lt;a
href="http://four.laravel.com/docs/migrations#database-seeding" title="laravel seed database"&gt;seeds&lt;/a&gt; to create a few sample users.&lt;/p&gt;&lt;p&gt;Create a file within the &lt;code&gt;app/database/seeds&lt;/code&gt; folder that has the same name as the table that it corresponds to; in our case, &lt;code&gt;UserTableSeeder.php&lt;/code&gt;. Add:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;&amp;lt;?php

class UserTableSeeder extends Seeder {

    public function run()
    {
        DB::table('users')-&amp;gt;delete();

        User::create(array(
            'username' =&amp;gt; 'firstuser',
            'password' =&amp;gt; Hash::make('first_password')
        ));

        User::create(array(
            'username' =&amp;gt; 'seconduser',
            'password' =&amp;gt; Hash::make('second_password')
        ));
    }

}
&lt;/pre&gt;&lt;p&gt;Next, make sure that seeder class gets run when the database is seeded. Edit &lt;code&gt;app/database/seeds/DatabaseSeeder.php&lt;/code&gt;:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;public function run()
{
    Eloquent::unguard();

    // Add or Uncomment this line
    $this-&amp;gt;call('UserTableSeeder');
}
&lt;/pre&gt;&lt;h3&gt;Run the Migrations&lt;/h3&gt;&lt;p&gt;Here&amp;#8217;s how to create those two tables, and insert our sample users.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;// Create the two tables
$ php artisan migrate

// Create the sample users
$ php artisan db:seed
&lt;/pre&gt;&lt;hr
/&gt;&lt;h2&gt;Models&lt;/h2&gt;&lt;p&gt;Laravel 4 continues to use the excellent Eloquent ORM. This will make the process of handling database calls a snap. We&amp;#39;ll require one model per table.&lt;/p&gt;&lt;p&gt;Luckily, Laravel comes with a User model setup, so let&amp;#39;s create a model for our urls table.&lt;/p&gt;&lt;p&gt;Create and edit file &lt;code&gt;app/models/Url.php&lt;/code&gt;.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;&amp;lt;?php

class Url extends Eloquent {

    protected $table = 'urls';

}
&lt;/pre&gt;&lt;hr
/&gt;&lt;h2&gt;Authentication&lt;/h2&gt;&lt;p&gt;Laravel&amp;#39;s &lt;a
href="http://four.laravel.com/docs/routing#route-filters" title="laravel filters"&gt;filters&lt;/a&gt; can handle authentication for us. In particular, Laravel now comes with a Basic Authentication filter, which we can use as a quick authentication model to be used with our API requests.&lt;/p&gt;&lt;p&gt;If you open &lt;code&gt;app/filters.php&lt;/code&gt;, you&amp;#39;ll see what it looks like:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;Route::filter('auth.basic', function()
{
    return Auth::basic();
});
&lt;/pre&gt;&lt;p&gt;We just need to make one adjustment. By default, this filter looks for an &amp;quot;email&amp;quot; field to identify the user. Since we&amp;#39;re using usernames instead of emails, we just need to adjust that preference. Change the &lt;code&gt;Auth::basic()&lt;/code&gt; call by giving it our username field as a parameter:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;Route::filter('auth.basic', function()
{
    return Auth::basic(&amp;quot;username&amp;quot;);
});
&lt;/pre&gt;&lt;h3&gt;Routes&lt;/h3&gt;&lt;p&gt;Let&amp;#39;s test this out. Create a route, called &lt;code&gt;testauth&lt;/code&gt;, and make sure that our &lt;code&gt;auth.basic&lt;/code&gt; filter runs before it.&lt;/p&gt;&lt;p&gt;Edit &lt;code&gt;app/routes.php&lt;/code&gt;:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;Route::get('/authtest', array('before' =&amp;gt; 'auth.basic', function()
{
    return View::make('hello');
}));
&lt;/pre&gt;&lt;p&gt;We can test this with a curl request. From your terminal, try pointing to your build of Laravel. In mine, it looks like this (Your URL will likely be different!):&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;$ curl -i localhost/l4api/public/index.php/authtest
HTTP/1.1 401 Unauthorized
Date: Tue, 21 May 2013 18:47:59 GMT
WWW-Authenticate: Basic
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8

Invalid credentials
&lt;/pre&gt;&lt;p&gt;As you can see, an unauthorized request is detected and a &amp;quot;Invalid Credentials&amp;quot; message is returned with a 401 status code. Next, try including basic authentication.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;$ curl --user firstuser:first_password localhost/l4api/public/index.php/authtest
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 18:50:51 GMT
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8

&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;
&lt;/pre&gt;&lt;p&gt;It worked!&lt;/p&gt;&lt;p&gt;At this point, the baseline work of our API is done. We have:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Installed Laravel 4&lt;/li&gt;&lt;li&gt;Created our database&lt;/li&gt;&lt;li&gt;Created our models&lt;/li&gt;&lt;li&gt;Created an authentication model&lt;/li&gt;&lt;/ul&gt;&lt;hr
/&gt;&lt;h2&gt;Creating Functional Requests&lt;/h2&gt;&lt;p&gt;You may be familiar with Laravel&amp;#39;s &lt;a
href="http://four.laravel.com/docs/controllers#restful-controllers" title="laravel restful controller"&gt;RESTful controllers&lt;/a&gt;. They still exist in Laravel 4; however, we can also use Laravel&amp;#39;s &lt;a
href="http://four.laravel.com/docs/controllers#resource-controllers" title="laravel resourceful controller"&gt;Resourceful Controllers&lt;/a&gt;, which set up some paradigms that we can use to make a consistent API interface. We&amp;#39;ll be using a Resourceful controller.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;a
href="http://four.laravel.com/docs/controllers#resource-controllers"&gt;Here&amp;#39;s a breakdown&lt;/a&gt; of what each method in the resourceful controller will handle. Please note that you can remove the /resource/create and /resource/{id}/edit routes, since we won&amp;#39;t be needing to show &amp;#39;create&amp;#39; or &amp;#39;edit&amp;#39; forms in an API.&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;Create a Resourceful Controller&lt;/h3&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ php artisan controller:make UrlController
&lt;/pre&gt;&lt;p&gt;Next, setup a route to use the controller, and require each route to be authenticated.&lt;/p&gt;&lt;p&gt;Edit &lt;code&gt;app/routes.php&lt;/code&gt; and add:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;// Route group for API versioning
Route::group(array('prefix' =&amp;gt; 'api/v1', 'before' =&amp;gt; 'auth.basic'), function()
{
    Route::resource('url', 'UrlController');
});
&lt;/pre&gt;&lt;p&gt;A few things are happening there.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;This is going to respond to requests made to &lt;code&gt;http://example.com/api/v1/url&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;This allows us to add extra routes, if we need to expand our API. For instance, if you add a user end-point, such as &lt;code&gt;/api/v1/user&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;There is also a naming mechanism in place for versioning our API. This gives us the opportunity to roll out new API versions without breaking older versions &amp;#8211; We can simply create a &lt;strong&gt;v2&lt;/strong&gt; route group, and point it to a new controller!&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Note: You may want to consider more advanced API versioning techniques, such as using an &lt;code&gt;Accept&lt;/code&gt; header or subdomain which can help you point different API versions separate code bases.&lt;/p&gt;&lt;h3&gt;Add the Functionality&lt;/h3&gt;&lt;p&gt;Edit the new &lt;code&gt;app/controllers/UrlController.php&lt;/code&gt; file:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;// Edit this:
public function index()
{
    return 'Hello, API';
}
&lt;/pre&gt;&lt;p&gt;Let&amp;#8217;s test it:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;$ curl -i localhost/l4api/public/index.php/api/v1/url
HTTP/1.1 401 Unauthorized
Date: Tue, 21 May 2013 19:02:59 GMT
WWW-Authenticate: Basic
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8

Invalid credentials.

$ curl --user firstuser:first_password localhost/l4api/public/index.php/api/v1/url
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 19:04:19 GMT
Vary: Accept-Encoding
Content-Type: text/html; charset=UTF-8

Hello, API
&lt;/pre&gt;&lt;p&gt;We now have a resourceful controller with authentication working, and are ready to add functionality.&lt;/p&gt;&lt;h3&gt;Create a URL&lt;/h3&gt;&lt;p&gt;Edit &lt;code&gt;app/controllers/UrlController.php&lt;/code&gt;:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;/**
 * Store a newly created resource in storage.
 *
 * @return Response
 */
public function store()
{
    $url = new Url;
    $url-&amp;gt;url = Request::get('url');
    $url-&amp;gt;description = Request::get('description');
    $url-&amp;gt;user_id = Auth::user()-&amp;gt;id;

    // Validation and Filtering is sorely needed!!
    // Seriously, I'm a bad person for leaving that out.

    $url-&amp;gt;save();

    return Response::json(array(
        'error' =&amp;gt; false,
        'urls' =&amp;gt; $urls-&amp;gt;toArray()),
        200
    );
}
&lt;/pre&gt;&lt;p&gt;It&amp;#39;s time to test this with another curl request. This one will send a POST request, which will correspond to the &lt;code&gt;store()&lt;/code&gt; method created above.&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ curl -i --user firstuser:first_password -d 'url=http://google.com&amp;amp;description=A Search Engine' localhost/l4api/public/index.php/api/v1/url
HTTP/1.1 201 Created
Date: Tue, 21 May 2013 19:10:52 GMT
Content-Type: application/json

{&amp;quot;error&amp;quot;:false,&amp;quot;message&amp;quot;:&amp;quot;URL created&amp;quot;}
&lt;/pre&gt;&lt;p&gt;Cool! Let&amp;#39;s create a few more, for both of our users.&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ curl --user firstuser:first_password -d 'url=http://fideloper.com&amp;amp;description=A Great Blog' localhost/l4api/public/index.php/api/v1/url

$ curl --user seconduser:second_password -d 'url=http://digitalsurgeons.com&amp;amp;description=A Marketing Agency' localhost/l4api/public/index.php/api/v1/url

$ curl --user seconduser:second_password -d 'url=http://www.poppstrong.com/&amp;amp;description=I feel for him' localhost/l4api/public/index.php/api/v1/url
&lt;/pre&gt;&lt;p&gt;Next, let&amp;#39;s create methods for retrieving URLs.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;/**
 * Display a listing of the resource.
 *
 * @return Response
 */
public function index()
{
    //Formerly: return 'Hello, API';

    $urls = Url::where('user_id', Auth::user()-&amp;gt;id)-&amp;gt;get();

    return Response::json(array(
        'error' =&amp;gt; false,
        'urls' =&amp;gt; $urls-&amp;gt;toArray()),
        200
    );
}

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return Response
 */
public function show($id)
{
    // Make sure current user owns the requested resource
    $url = Url::where('user_id', Auth::user()-&amp;gt;id)
            -&amp;gt;where('id', $id)
            -&amp;gt;take(1)
            -&amp;gt;get();

    return Response::json(array(
        'error' =&amp;gt; false,
        'urls' =&amp;gt; $url-&amp;gt;toArray()),
        200
    );
}
&lt;/pre&gt;&lt;p&gt;Let&amp;#39;s test them out:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ curl --user firstuser:first_password localhost/l4api/public/index.php/api/v1/url
{
    &amp;quot;error&amp;quot;: false,
    &amp;quot;urls&amp;quot;: [
       {
            &amp;quot;created_at&amp;quot;: &amp;quot;2013-02-01 02:39:10&amp;quot;,
            &amp;quot;description&amp;quot;: &amp;quot;A Search Engine&amp;quot;,
            &amp;quot;id&amp;quot;: &amp;quot;2&amp;quot;,
            &amp;quot;updated_at&amp;quot;: &amp;quot;2013-02-01 02:39:10&amp;quot;,
            &amp;quot;url&amp;quot;: &amp;quot;http://google.com&amp;quot;,
            &amp;quot;user_id&amp;quot;: &amp;quot;1&amp;quot;
        },
        {
            &amp;quot;created_at&amp;quot;: &amp;quot;2013-02-01 02:44:34&amp;quot;,
            &amp;quot;description&amp;quot;: &amp;quot;A Great Blog&amp;quot;,
            &amp;quot;id&amp;quot;: &amp;quot;3&amp;quot;,
            &amp;quot;updated_at&amp;quot;: &amp;quot;2013-02-01 02:44:34&amp;quot;,
            &amp;quot;url&amp;quot;: &amp;quot;http://fideloper.com&amp;quot;,
            &amp;quot;user_id&amp;quot;: &amp;quot;1&amp;quot;
        }
    ]
}

$ curl --user firstuser:first_password localhost/l4api/public/index.php/api/v1/url/1
{
    &amp;quot;error&amp;quot;: false,
    &amp;quot;urls&amp;quot;: [
        {
            &amp;quot;created_at&amp;quot;: &amp;quot;2013-02-01 02:39:10&amp;quot;,
            &amp;quot;description&amp;quot;: &amp;quot;A Search Engine&amp;quot;,
            &amp;quot;id&amp;quot;: &amp;quot;2&amp;quot;,
            &amp;quot;updated_at&amp;quot;: &amp;quot;2013-02-01 02:39:10&amp;quot;,
            &amp;quot;url&amp;quot;: &amp;quot;http://google.com&amp;quot;,
            &amp;quot;user_id&amp;quot;: &amp;quot;1&amp;quot;
        }
    ]
}
&lt;/pre&gt;&lt;p&gt;Almost done. Let&amp;#39;s now allow users to delete a url.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;/**
 * Remove the specified resource from storage.
 *
 * @param  int  $id
 * @return Response
 */
public function destroy($id)
{
    $url = Url::where('user_id', Auth::user()-&amp;gt;id)-&amp;gt;find($id);

    $url-&amp;gt;delete();

    return Response::json(array(
        'error' =&amp;gt; false,
        'message' =&amp;gt; 'url deleted'),
        200
        );
}
&lt;/pre&gt;&lt;p&gt;Now, we can delete a URL by using a DELETE request:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ curl -i -X DELETE --user firstuser:first_password localhost/l4api/public/index.php/api/v1/url/1
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 19:24:19 GMT
Content-Type: application/json

{&amp;quot;error&amp;quot;:false,&amp;quot;message&amp;quot;:&amp;quot;url deleted&amp;quot;}
&lt;/pre&gt;&lt;p&gt;Lastly, let&amp;#39;s allow users to update a url.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;/**
 * Update the specified resource in storage.
 *
 * @param  int  $id
 * @return Response
 */
public function update($id)
{
    $url = Url::where('user_id', Auth::user()-&amp;gt;id)-&amp;gt;find($id);

    if ( Request::get('url') )
    {
        $url-&amp;gt;url = Request::get('url');
    }

    if ( Request::get('description') )
    {
        $url-&amp;gt;description = Request::get('description');
    }

    $url-&amp;gt;save();

    return Response::json(array(
        'error' =&amp;gt; false,
        'message' =&amp;gt; 'url updated'),
        200
    );
}
&lt;/pre&gt;&lt;p&gt;To test URL updates, run:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;$ curl -i -X PUT --user seconduser:second_password -d 'url=http://yahoo.com' localhost/l4api/public/index.php/api/v1/url/4
HTTP/1.1 200 OK
Date: Tue, 21 May 2013 19:34:21 GMT
Content-Type: application/json

{&amp;quot;error&amp;quot;:false,&amp;quot;message&amp;quot;:&amp;quot;url updated&amp;quot;}

// View our changes
$ curl --user seconduser:second_password localhost/l4api/public/index.php/api/v1/url/4
{
    &amp;quot;error&amp;quot;: false,
    &amp;quot;urls&amp;quot;: [
        {
            &amp;quot;created_at&amp;quot;: &amp;quot;2013-02-01 02:44:34&amp;quot;,
            &amp;quot;description&amp;quot;: &amp;quot;I feel for him&amp;quot;,
            &amp;quot;id&amp;quot;: &amp;quot;3&amp;quot;,
            &amp;quot;updated_at&amp;quot;: &amp;quot;2013-02-02 18:44:18&amp;quot;,
            &amp;quot;url&amp;quot;: &amp;quot;http://yahoo.com&amp;quot;,
            &amp;quot;user_id&amp;quot;: &amp;quot;1&amp;quot;
        }
    ]
}
&lt;/pre&gt;&lt;hr
/&gt;&lt;h2&gt;And That&amp;#8217;s It&lt;/h2&gt;&lt;p&gt;We now have the beginnings of a fully-functioning API. I hope that you&amp;#39;ve learned a lot about how to get an API underway with Laravel 4.&lt;/p&gt;&lt;p&gt;To recap, we achieved the following in this lesson:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Install Laravel&lt;/li&gt;&lt;li&gt;Create the database, using migrations and seeding&lt;/li&gt;&lt;li&gt;Use Eloquent ORM models&lt;/li&gt;&lt;li&gt;Authenticate with Basic Auth&lt;/li&gt;&lt;li&gt;Set up Routes, including versioning the API&lt;/li&gt;&lt;li&gt;Create the API functionality using Resourceful Controllers&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;The Next Steps&lt;/h3&gt;&lt;p&gt;If you&amp;#8217;d like to push your API up a notch, you might consider any of the following as a next step.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Validation (Hint: Laravel has a &lt;a
href="http://four.laravel.com/docs/validation"&gt;Validation library&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;API-request error handling – It&amp;#39;s still possible to receive HTML response on API requests (Hint: &lt;a
href="http://fideloper.com/laravel4-error-handling" title="laravel error handling"&gt;Laravel Error Handling&lt;/a&gt;, plus Content Negotiation.)&lt;/li&gt;&lt;li&gt;Content Negotiation &amp;#8211; listening for the Accept header. (Hint: &lt;a
href="http://four.laravel.com/docs/requests#request-information" title="Laravel request class"&gt;Laravel&amp;#39;s Request Class&lt;/a&gt; will give you the request headers).&lt;/li&gt;&lt;li&gt;Check out the &lt;a
href="http://groups.google.com/group/api-craft/"&gt;API Craft Google Group&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Learn about the &lt;a
href="http://fideloper.com/quick-caching-explanation?utm_source=nettuts&amp;amp;utm_medium=article&amp;amp;utm_content=api&amp;amp;utm_campaign=guest_author" title="http cache"&gt;different types caching&lt;/a&gt; and how Validation Caching can improve your API&lt;/li&gt;&lt;li&gt;&lt;a
href="leanpub.com/laravel-testing-decoded"&gt;Unit test your code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Check out &lt;a
href="http://apigee.com/about/api-best-practices"&gt;Apigee&amp;#39;s great API resources&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=iseZmkJPwRw:EEVf3cVY1aU:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=iseZmkJPwRw:EEVf3cVY1aU:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=iseZmkJPwRw:EEVf3cVY1aU:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=iseZmkJPwRw:EEVf3cVY1aU:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=iseZmkJPwRw:EEVf3cVY1aU:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=iseZmkJPwRw:EEVf3cVY1aU:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=iseZmkJPwRw:EEVf3cVY1aU:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=iseZmkJPwRw:EEVf3cVY1aU:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/iseZmkJPwRw" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/php/laravel-4-a-start-at-a-restful-api/feed/</wfw:commentRss> <slash:comments>61</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/php/laravel-4-a-start-at-a-restful-api/</feedburner:origLink></item> <item><title>The Right Way to Retinafy Your Websites</title><link>http://feedproxy.google.com/~r/nettuts/~3/og52Nv0vAjs/</link> <comments>http://net.tutsplus.com/tutorials/html-css-techniques/the-right-way-to-retinafy-your-websites/#comments</comments> <pubDate>Tue, 21 May 2013 14:55:30 +0000</pubDate> <dc:creator>Allan Berger</dc:creator> <category><![CDATA[HTML & CSS]]></category> <category><![CDATA[retina]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31793</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31793&amp;c=1935524149' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31793&amp;c=1935524149' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt; Making your website ready for Retina display doesn&amp;rsquo;t have to be a hassle. Whether you are building a new website or upgrading an existing one, this guide is designed to help you get the job done smoothly.&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31793"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Make it Retina First&lt;/h2&gt;&lt;p&gt; The easiest and most time-saving way to add Retina support is to create one image that is optimized for Retina devices, and serve it to non-Retina devices as well.&lt;/p&gt;&lt;p&gt; By now, every &lt;a
href="http://stackoverflow.com/questions/3382376/is-it-acceptable-to-leave-image-resizing-up-to-the-client-browser" target="_blank"&gt;modern browser&lt;/a&gt; uses bicubic resampling and does a great job with downsampling images. Here&amp;#8217;s a comparison of downsampling in Photoshop vs. Google Chrome, using an image from our &lt;a
href="http://www.growthengineering101.com" target="_blank"&gt;Growth Engineering 101&lt;/a&gt; website.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Growth Engineering 101" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/growth-hacking-image-1.png" /&gt;&lt;/figure&gt;&lt;p&gt; There are two ways to let the browser downsample images for you: &lt;code&gt;img&lt;/code&gt; tags or CSS background images.&lt;/p&gt;&lt;p&gt; You can have &lt;code&gt;img&lt;/code&gt; tags serve the Retina-optimized image, and set the width and height attributes to half of the resolution of the actual image (e.g. &lt;em&gt;400&amp;#215;300&lt;/em&gt; if the image dimensions are &lt;em&gt;800&amp;#215;600&lt;/em&gt;).&lt;/p&gt;&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;img src=&amp;quot;http://www.example.com/Retina-image-800x600-2x.png&amp;quot; width=&amp;quot;400&amp;quot; height=&amp;quot;300&amp;quot;&amp;gt;
&lt;/pre&gt;&lt;p&gt; If you use images as CSS backgrounds, you may use the CSS3 &lt;code&gt;background-size&lt;/code&gt; property to downsample the image for non-Retina devices.&lt;/p&gt;&lt;pre class="brush: xml; title: ; notranslate"&gt;
&amp;lt;div class=&amp;quot;photo&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;
&lt;/pre&gt;&lt;pre class="brush: css; title: ; notranslate"&gt;
.photo {
    background-image: url(Retina-image-800x600-2x.png);
    background-size: 400px 300px;
    background-repeat: no-repeat;
    display: block;
    width: 400px;
    height: 300px;
}
&lt;/pre&gt;&lt;p&gt; In both cases, be sure to use even numbers in both dimensions to prevent displacement of pixels when the image is being downsampled by the browser.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;When Downsampling is Not Good Enough&lt;/h2&gt;&lt;p&gt; Usually, browser downsampling should work quite well. That said, there are some situations where downsampling in the browser might make images blurry.&lt;/p&gt;&lt;p&gt; Here we have a bunch of &lt;code&gt;32px&lt;/code&gt; social icons.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="32x32 px social icons" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/32pixel-icons-2.png" /&gt;&lt;/figure&gt;&lt;p&gt; And here is how they will appear, when downsampled to &lt;code&gt;16px&lt;/code&gt; by Photoshop&amp;rsquo;s as well as Google Chrome&amp;rsquo;s bicubic filter. It seems that we get better results from Photoshop in this case.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="16x16 px social icons - Transparent BG - Chrome vs Photoshop" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/16pixel-icons-3.png" /&gt;&lt;/figure&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="16x16 px social icons - White BG - Chrome vs Photoshop" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/16pixel-icons-4.png" /&gt;&lt;/figure&gt;&lt;p&gt; To get the best results for our users, we can create two versions of the same image: one for Retina devices, and another one that has been downsampled by Photoshop for non-Retina devices.&lt;/p&gt;&lt;p&gt; Now, you can use CSS media queries to serve Retina or non-Retina images, dependent upon the pixel density of the device.&lt;/p&gt;&lt;pre class="brush: css; title: ; notranslate"&gt;
/* CSS for devices with normal screens */
.icons {
    background-image: url(icon-sprite.png);
    background-repeat: no-repeat;
}
&lt;/pre&gt;&lt;pre class="brush: css; title: ; notranslate"&gt;/* CSS for high-resolution devices */
@media only screen and (-Webkit-min-device-pixel-ratio: 1.5),
only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
    .icons {
        background-image: url(icon-sprite-2x.png);
        background-size: 200px 100px;
        background-repeat: no-repeat;
    }
}
&lt;/pre&gt;&lt;p&gt; If you use a background color for small icons, on the other hand, downsampling by the browser works rather well. Here is the same downsampling example with a white background.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="16x16 px social icons - Zoom 200%" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/16pixel-zoom-5.png" /&gt;&lt;/figure&gt;&lt;hr
/&gt;&lt;h2&gt;Polishing Your Downsampled Images&lt;/h2&gt;&lt;p&gt; If you&amp;rsquo;re still not satisfied with the results from Photoshop&amp;rsquo;s downsampling, you can go the extra mile and &lt;em&gt;hand-optimize&lt;/em&gt; the non-Retina version to get super crisp results.&lt;/p&gt;&lt;p&gt; Below are some examples of images from the &lt;a
href="https://www.blossom.io" target="_blank"&gt;Blossom&lt;/a&gt; product website that I &lt;em&gt;hand-optimized&lt;/em&gt; for those who are still on non-Retina devices.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Borders and Strokes&lt;/h2&gt;&lt;p&gt; Here&amp;#8217;s an example of downsampling issues with hairlines, where I re-draw the lines of the downsampled image.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Borders and Strokes - Teaser Image" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/product-teaser-preview-6.png" /&gt;&lt;/figure&gt;&lt;p&gt; View the Retina Version of this Image on &lt;a
href="http://dribbble.com/shots/1047231-Blossom-Retina-Ready-Landing-Page/attachments/127611" target="_blank"&gt;Dribbble&lt;/a&gt;.&lt;/br&gt;&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Borders and Strokes - Photoshop vs Chrome" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/product-teaser-optim-7.png" /&gt;&lt;/figure&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Borders and Strokes - Photoshop vs Hand" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/product-teaser-optim-8.png" /&gt;&lt;/figure&gt;&lt;hr
/&gt;&lt;h2&gt;Text&lt;/h2&gt;&lt;p&gt; Next, we come to an example of downsampling issues with text. In this case, I manually re-wrote the text &amp;ldquo;Feature Pipeline&amp;rdquo; to make the result as crisp as possible.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Text - Original" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/text-retina-9.png" /&gt;&lt;/figure&gt;&lt;p&gt;&lt;/p&gt;&lt;h5&gt;Retina Version&lt;/h5&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Text - Photoshop vs Hand" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/text-comparison-10.png" /&gt;&lt;/figure&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Text - Photoshop vs Chrome" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/text-comparison-11.png" /&gt;&lt;/figure&gt;&lt;p&gt; When details, crisp fonts, and clean hairlines are important, you might want to go the extra mile.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Try to Avoid Images&lt;/h2&gt;&lt;p&gt; The main disadvantages of rasterized images are their considerable file size and that they don&amp;rsquo;t scale well to different sizes without affecting the image quality. Great alternatives to rasterized graphics are CSS, Scalable Vector Graphics (SVG), and Icon Fonts.&lt;/p&gt;&lt;p&gt; If you have any chance to build the graphical elements for your website in CSS, go for it. It can be used to add gradients, borders, rounded corners, shadows, arrows, rotate elements and much more.&lt;/p&gt;&lt;p&gt; Here are a few examples of interaction elements in Blossom that are implemented in CSS. The subtle gradient is powered by CSS gradients, and the custom font in use on this button is Kievit, served via &lt;a
href="https://typekit.com/"&gt;Typekit&lt;/a&gt;. No images.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="CSS Solution - Button" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/css-button-12.png" /&gt;&lt;/figure&gt;&lt;p&gt; In the following screenshot, the only two images used are the user avatar and the blue stamp. Everything else &amp;ndash; the circled question mark, the dark grey arrow next to it, the popover, its shadow and the arrow on top of it &amp;ndash; is pure HTML and CSS.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="CSS Solution - Popover" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/css-overlay-13.png" /&gt;&lt;/figure&gt;&lt;p&gt; Here, you can see how projects in Blossom appear. It&amp;rsquo;s a screenshot of a project&amp;rsquo;s website used as cover on a stack of paper sheets. The paper sheets are implemented with &lt;code&gt;div&lt;/code&gt;s that are rotated using CSS.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="CSS Solution - Stack" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/css-product-cover-14.png" /&gt;&lt;/figure&gt;&lt;p&gt; Also, the circled arrow in the right-hand side of the screenshot below is pure CSS.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="CSS Solution - Circled Arrow" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/css-organization-switcher-15.png" /&gt;&lt;/figure&gt; &lt;/figure&gt;&lt;h3&gt;Tools&lt;/h3&gt;&lt;p&gt; Here are some awesome tools that will help save time when creating effects with CSS.&lt;/p&gt;&lt;ul&gt;&lt;li&gt; &lt;strong&gt;&lt;a
href="http://css3generator.com/" target="_blank"&gt;CSS Generator&lt;/a&gt;:&lt;/strong&gt; Cross browser CSS3 syntax by &lt;a
href="https://twitter.com/RandyJensen"&gt;@RandyJensen&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;&lt;a
href="http://cssarrowplease.com/" target="_blank"&gt;CSS Arrows:&lt;/a&gt;&lt;/strong&gt; CSS for tooltip arrows by &lt;a
href="https://twitter.com/ShojBerg"&gt;@ShojBerg&lt;/a&gt;.&lt;/li&gt;&lt;li&gt; &lt;strong&gt;&lt;a
href="http://spritecow.com/" target="_blank"&gt;Generating CSS for Sprites&lt;/a&gt;:&lt;/strong&gt; Sprite Cow helps you get the background-position, width and height of sprites within a spritesheet as a nice bit of copyable css. It&amp;rsquo;s built by &lt;a
href="http://theteam.co.uk/" target="_blank"&gt;TheTeam&lt;/a&gt;, and is a real time saver &amp;#8211; definitely worth a try.&lt;/li&gt;&lt;/ul&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Scalable Vector Graphic" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/svg-16.png" /&gt;&lt;/figure&gt;&lt;p&gt; The primary advantage to &lt;a
href="http://en.wikipedia.org/wiki/Scalable_Vector_Graphics" target="_blank"&gt;SVG&lt;/a&gt; is that, unlike rasterized graphics, they scale reasonably well to various sizes. If you&amp;#8217;re working with simple shapes, they typically are  smaller than PNGs. Often, they are used for things like charts.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Icon Fonts" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/icon-fonts-17.png" /&gt;&lt;/figure&gt;&lt;p&gt; &lt;a
href="http://weloveiconfonts.com/" target="_blank"&gt;Icon Fonts&lt;/a&gt; are frequently used as a replacement for image sprites. Similar to SVG, they can be scaled up infinitely without any loss of quality and are usually smaller in size, when compared to image sprites. On top of that, you can use CSS to change their size, color and even add effects, such as shadows.&lt;/p&gt;&lt;p&gt; Both SVG and Icon Fonts are well supported by modern browsers.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Retina-Ready Favicons&lt;/h2&gt;&lt;p&gt; Favicons are really important for users who need an easy way to remember which website belongs to which browser tab. A Retina-ready Favicon will not only be easier to identify, but it will also stand out among a crowd of pixelated Favicons that haven&amp;#8217;t yet been optimized.&lt;/p&gt;&lt;p&gt; To make your Favicon Retina-ready, I highly recommend &lt;a
href="http://www.xiconeditor.com/" target="_blank"&gt;X-Icon Editor&lt;/a&gt;. You can either upload a single image and let the editor resize it for different dimensions, or you can upload separate images optimized for each size to get the best results.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="X-Icon Editor" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/x-icon-editor-18.png" width="600" /&gt;&lt;/figure&gt;&lt;hr
/&gt;&lt;h2&gt;How to Make Existing Images Retina-Ready&lt;/h2&gt;&lt;p&gt; If you want to upgrade a website with existing images, a bit more work is required, as you&amp;#8217;ll need to re-create all images to make them Retina-ready, but this doesn&amp;rsquo;t have to waste too much time.&lt;/p&gt;&lt;p&gt; First, attempt to identify images that you can avoid by using alternatives like CSS, SVG and Image Fonts, as noted previously. Buttons, Icons and other common UI widgets usually can be replaced with modern solutions that don&amp;rsquo;t require any images.&lt;/p&gt;&lt;p&gt; In case you actually need to re-create rasterized images, you&amp;#8217;ll of course want to return to the source files. As you might assume, simply resizing your rasterized bitmap images to be twice as big doesn&amp;rsquo;t get the job done, because all of the details and borders will become pixelated.&lt;/p&gt;&lt;p&gt; No need to despair &amp;ndash; image compositions which mostly contain vectors (i.e. in Adobe Photoshop or Illustrator) are quite easy to scale up. That said, don&amp;rsquo;t forget to verify if your Photoshop effects in the blending options, such as strokes, shadows and bevels, still appear as you intended.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt; In general, making Photoshop compositions directly out of vectors (shapes) and Photoshop&amp;rsquo;s &lt;em&gt;Smart Objects&lt;/em&gt; will save you a great deal of time in the future.&lt;/p&gt;&lt;/blockquote&gt;&lt;hr
/&gt;&lt;h2&gt;How to Optimize the File Size of Images&lt;/h2&gt;&lt;p&gt; Last, but not least, optimizing the file size of all images in an application or website could effectively save up to 90% of image loading times. When it comes to Retina images, the file size reduction gets even more important, as they have a higher pixel density that will increase their respective file sizes.&lt;/p&gt;&lt;p&gt; In Photoshop, you can optimize the image file size, via the &amp;ldquo;Save for Web&amp;rdquo; feature. On top of that, there is an excellent free tool, called &lt;a
href="http://pngmini.com/" target="_blank"&gt;ImageAlpha&lt;/a&gt;, which can reduce the size of your images even more with just a minor loss of quality.&lt;/p&gt;&lt;p&gt; Unlike Photoshop, ImageApha can convert 24-bit alpha channel PNGs to 8-bit PNGs with alpha channel support. The icing on the cake is that these optimized images are cross-browser compatible and even work for IE6!&lt;/p&gt;&lt;p&gt; You can play around with different settings in ImageAlpha to get the right trade-off between quality and file size. In the case below, we can reduce the file size by nearly 80%.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Image Alpha" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/image-alpha-19.png" width="600" /&gt;&lt;/figure&gt;&lt;p&gt; When you&amp;#8217;re finished setting your desired compression levels, ImageAlpha&amp;rsquo;s save dialog also offers to &amp;ldquo;Optimize with &lt;a
href="http://imageoptim.com/" target="_blank"&gt;ImageOptim&lt;/a&gt;&amp;rdquo; &amp;#8211; another great and free tool.&lt;/p&gt;&lt;p&gt; ImageOptim automatically picks the best compression options for your image and removes unnecessary meta information and color profiles. In the case of our stamp file, ImageOptim was able to reduce the file size by another 34%.&lt;/p&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Image Optim" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/image-optim-20.png" /&gt;&lt;/figure&gt;&lt;p&gt; After we updated all assets at &lt;a
href="https://www.blossom.io" target="_blank"&gt;Blossom.io&lt;/a&gt; for high resolution displays and used ImageAlpha and ImageOptim to optimize the file size, we actually ended up saving a few kilobytes in comparison to the assets we had before.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Save Time, Read This Book&lt;/h2&gt; &lt;figure
class="tutorial_image"&gt;&lt;a
href="http://Retinafy.me/" target="_blank"&gt;&lt;img
alt="Retinafy.me - Retinafy your Websites and Apps" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/retinafy.png" width="200" height="248" /&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p&gt; If you want to learn more about how to get your apps and websites ready for Retina displays, I highly recommend &lt;a
href="http://Retinafy.me/" target="_blank"&gt;&amp;#8220;Retinafy your web sites &amp;amp; apps&amp;#8221;&lt;/a&gt;, by Thomas Fuchs. It&amp;rsquo;s a straight-forward step by step guide that saved me a lot of time and nerves.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Awesome Retina-Ready Sites on the Web&lt;/h2&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Kickoff" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/kickoff-600.png" /&gt;&lt;br
/&gt;&lt;a
href="http://kickoffapp.com/" target="_blank"&gt;http://kickoffapp.com/&lt;/a&gt;&lt;/figure&gt;&lt;hr
/&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="LayerVault" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/layervault-600.png"&gt;&lt;br
/&gt; &lt;a
href="http://www.layervault.com" target="_blank"&gt;http://www.layervault.com&lt;/a&gt;&lt;br
/&gt; &lt;/figure&gt;&lt;hr
/&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Apple" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/apple-600.png"&gt;&lt;br
/&gt; &lt;a
href="http://www.apple.com" target="_blank"&gt;http://www.apple.com&lt;/a&gt;&lt;br
/&gt; &lt;/figure&gt;&lt;hr
/&gt; &lt;figure
class="tutorial_image"&gt;&lt;img
alt="Panic" src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/panic-600.png"&gt;&lt;/p&gt;&lt;p&gt;&lt;a
href="http://www.panic.com" target="_blank"&gt;http://www.panic.com&lt;/a&gt;&lt;br
/&gt; &lt;/figure&gt;&lt;p&gt;Thanks for reading! Any questions?&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=og52Nv0vAjs:R57WSSnXO78:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=og52Nv0vAjs:R57WSSnXO78:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=og52Nv0vAjs:R57WSSnXO78:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=og52Nv0vAjs:R57WSSnXO78:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=og52Nv0vAjs:R57WSSnXO78:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=og52Nv0vAjs:R57WSSnXO78:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=og52Nv0vAjs:R57WSSnXO78:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=og52Nv0vAjs:R57WSSnXO78:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/og52Nv0vAjs" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/html-css-techniques/the-right-way-to-retinafy-your-websites/feed/</wfw:commentRss> <slash:comments>22</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/html-css-techniques/the-right-way-to-retinafy-your-websites/</feedburner:origLink></item> <item><title>How to Create a PyroCMS Theme</title><link>http://feedproxy.google.com/~r/nettuts/~3/o44IlSNrSVQ/</link> <comments>http://net.tutsplus.com/tutorials/php/how-to-create-a-pyrocms-theme/#comments</comments> <pubDate>Mon, 20 May 2013 16:00:33 +0000</pubDate> <dc:creator>Zac Vineyard</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[pyrocms]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31771</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31771&amp;c=652827484' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31771&amp;c=652827484' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;Like most content management systems, &lt;a
href="https://www.pyrocms.com/"&gt;PyroCMS&lt;/a&gt; uses front-end themes. Though PyroCMS themes are built a bit differently than what you might be used to from other systems, they&amp;#8217;re still quite easy to create. They&amp;#8217;re so easy, in fact, that very little PHP experience is required to assemble them!&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31771"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;The Folder Structure&lt;/h2&gt;&lt;p&gt;PyroCMS themes consist of HTML, images, CSS, and JavaScript, arranged into the following supported folders:&lt;/p&gt;&lt;ul&gt;&lt;li&gt; css&lt;/li&gt;&lt;li&gt; img&lt;/li&gt;&lt;li&gt; js&lt;/li&gt;&lt;li&gt; views&lt;/li&gt;&lt;li&gt; views/layouts&lt;/li&gt;&lt;li&gt; views/partials&lt;/li&gt;&lt;li&gt; views/modules&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;While these folders will no doubt look familiar to you, the &amp;quot;views&amp;quot; folder makes the most sense within the context of MVC. When building a theme for PyroCMS, you are really building the views (including assets) of a MVC patterned application. These views consist of a master layout file and multiple partial files (i.e. a &lt;code&gt;header.html&lt;/code&gt; or &lt;code&gt;footer.html&lt;/code&gt;) that shares presentation logic between different layouts. We&amp;#8217;ll discuss this more shortly.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Getting Started&lt;/h2&gt;&lt;p&gt;To get started building your first PyroCMS theme, create the supported folder structure in one of the two places that themes may reside within an instance of PyroCMS:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;addons/shared_addons/themes (for themes available to all sites)
&lt;/pre&gt;&lt;p&gt;Or:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
addons/[site-name]/themes (for themes available to only one specific site)
&lt;/pre&gt;&lt;p&gt;Once you have the base theme folder containing the supported folder structure created, the first file that you&amp;#39;ll want to add to your theme is &lt;code&gt;theme.php&lt;/code&gt;.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;addons/shared_addons/themes/[my-theme-name]/theme.php
&lt;/pre&gt;&lt;p&gt;This &lt;code&gt;theme.php&lt;/code&gt; file contains all essential details for your theme, including its name, author, version, etc. In a way, this file is similar to the comment block found at the top of a WordPress theme&amp;#39;s &lt;code&gt;style.css&lt;/code&gt; file. Here&amp;#8217;s a basic example of a &lt;code&gt;theme.php&lt;/code&gt; file for your PyroCMS theme:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;&amp;lt;?php defined('BASEPATH') OR exit('No direct script access allowed');

class Theme_Foo extends Theme
{
    public $name = 'Foo';
    public $author = 'Zac Vineyard';
    public $author_website = 'http://zacvineyard.com';
    public $website = 'http://example.com/themes/foo';
    public $description = 'The antithesis theme to your Bar theme.';
    public $version = '1.0';
}

 /* End of file theme.php */
&lt;/pre&gt;&lt;p&gt;Please take note that this file extends a PyroCMS class, called &lt;code&gt;Theme&lt;/code&gt;. Also, because you are declaring a PHP class in this file, you&amp;#39;ll need to make sure that the name of the folder containing your theme is used in the class declaration. So, if the folder housing your theme is called, &amp;quot;foo,&amp;quot; the class created in your &lt;code&gt;theme.php&lt;/code&gt; should be named, &lt;code&gt;Theme_Foo&lt;/code&gt; (instead of &lt;code&gt;Theme_Custom&lt;/code&gt;, as shown in the example within PyroCMS&amp;#39; documentation).&lt;/p&gt;&lt;p&gt;Once you have created your &lt;code&gt;theme.php&lt;/code&gt; file, you can login to your PyroCMS control panel and view your theme listed in the Themes module.&lt;/p&gt; &lt;figure
class=tutorial_image&gt;&lt;img
src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/pyrocms_theme1.png" alt="Choose a theme in the PyroCMS control panel" width="647" height="407"/&gt;&lt;/figure&gt;&lt;hr
/&gt;&lt;h2&gt;Layouts&lt;/h2&gt;&lt;p&gt;All layouts files for a PyroCMS theme exist in one of two locations:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;addons/[site-ref]/themes/[my-theme-name]/views/layouts/
&lt;/pre&gt;&lt;p&gt;Or:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
addons/shared_addons/themes/[my-theme-name]/views/layouts/
&lt;/pre&gt;&lt;p&gt;Every theme should have a layout file, named &amp;quot;default.html&amp;quot; in one of the locations listed above. Additional layout files are optional; I&amp;#39;ll show you how to add more layout files in a moment. First, it&amp;#8217;s important to review the contents of a layout file.&lt;/p&gt;&lt;p&gt;Layout files in PyroCMS are built using HTML and a tag parser, referred to as the Lex Tag Parser. This is what a very basic PyroCMS layout file looks like:&lt;/p&gt;&lt;pre class="brush: xml; title: ; notranslate"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;{{ template:title }}&amp;lt;/title&amp;gt;
    {{ template:metadata }}
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;{{ template:title }}&amp;lt;/h1&amp;gt;
    {{ template:body }}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;p&gt;The special tags you see in this bit of HTML are Lex parser tags. If you&amp;#39;ve ever used Smarty templates in PHP, these may look somewhat familiar. The primary benefit to using Lex parser tags in your layout files is that you don&amp;#39;t have to put PHP directly in your views (remember, we&amp;#39;re using MVC), which gives you the best chance of creating PyroCMS themes that follow the &lt;em&gt;don&amp;#8217;t repeat yourself&lt;/em&gt; pattern.&lt;/p&gt;&lt;p&gt;The example that I&amp;#39;ve given above is simple, of course, but Lex parser tags are quite powerful. They can loop through data, work with attributes, and more. &lt;a
href="http://docs.pyrocms.com/2.2/manual/guides/pyrocms-tags"&gt;Learn more about the Lex Parser&lt;/a&gt; in the PyroCMS documentation.&lt;/p&gt;&lt;p&gt;A more complex PyroCMS layout file looks like this:&lt;/p&gt;&lt;pre class="brush: xml; title: ; notranslate"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;{{ template:title }}&amp;lt;/title&amp;gt;
    {{ template:metadata }}
    {{ theme:favicon file=&amp;quot;favicon.png&amp;quot; }}
    {{ theme:css file=&amp;quot;style.css&amp;quot; }}
    {{ theme:js file=&amp;quot;site.js&amp;quot; }}
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;div class=&amp;quot;header&amp;quot;&amp;gt;
        &amp;lt;div class=&amp;quot;logo&amp;quot;&amp;gt;
            {{ theme:image file=&amp;quot;logo.jpg&amp;quot; alt=&amp;quot;Your Cool Logo&amp;quot; }}
        &amp;lt;/div&amp;gt;
        &amp;lt;div class=&amp;quot;nav&amp;quot;&amp;gt;
            {{ navigation:links group=&amp;quot;header&amp;quot; }}
        &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;
        &amp;lt;h1&amp;gt;{{ template:title }}&amp;lt;/h1&amp;gt;
        {{ template:body }}
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;&lt;p&gt;You&amp;#39;ll notice that this layout file, using Lex, includes assets, like CSS, JavaScript, and images. Using Lex tags and HTML allows PyroCMS developers to build layout files very quickly.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Partials&lt;/h2&gt;&lt;p&gt;Partials in PyroCMS, which stands for partial layouts, allows you to break layouts into reusable parts or sections. These sections can then be loaded by different layout files. This keeps you from typing the same code (header, footer, etc.) into multiple layout files.&lt;/p&gt;&lt;p&gt;Depending on where you&amp;#39;ve placed your theme files, partials are created in one of two locations:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;addons/[site-ref]/themes/[my-theme-name]/views/partials/
&lt;/pre&gt;&lt;p&gt;Or:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
addons/shared_addons/themes/[my-theme-name]/views/partials/
&lt;/pre&gt;&lt;p&gt;Partials are loaded into layouts using this Lex tag:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;{{ theme:partial name=&amp;quot;partialname&amp;quot; }}
&lt;/pre&gt;&lt;p&gt;This Lex tag operates exactly like a PHP &lt;code&gt;include&lt;/code&gt; statement &amp;#8211; similar to one that you would find in WordPress or other themes. The code below is a simple example of a PyroCMS layout that takes advantage of partials.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;{{ theme:partial name=&amp;quot;header&amp;quot; }}

    &amp;lt;div class=&amp;quot;content&amp;quot;&amp;gt;
        &amp;lt;h1&amp;gt;{{ template:title }}&amp;lt;/h1&amp;gt;
        {{ template:body }}
    &amp;lt;/div&amp;gt;

{{ theme:partial name=&amp;quot;footer&amp;quot; }}
&lt;/pre&gt;&lt;p&gt;The contents of the &lt;code&gt;header.html&lt;/code&gt; partial and &lt;code&gt;footer.html&lt;/code&gt; files are, of course, the HTML we&amp;#39;ll need to reuse from the template in our previous code example above. One quick pointer: there is no limit to the number of partials that you can use in one layout. Additionally, partial files may contain any combination of valid HTML and Lex.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Multiple Layout Files&lt;/h2&gt;&lt;p&gt;To add another layout to your instance of PyroCMS, create one more layout file in your theme&amp;#39;s &lt;em&gt;views/layouts/&lt;/em&gt; directory. This file may receive any name, but it&amp;#8217;s a good idea to name it as descriptively as possible &amp;#8211; like &lt;code&gt;about.html&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;For added flexibility, you can make use of as many layout files as you&amp;#39;d like. When you edit or create a &lt;em&gt;Page Type&lt;/em&gt; in your PyroCMS control panel (&lt;em&gt;Control Panel&amp;rarr;Pages&amp;rarr;Page Types&lt;/em&gt;) and select your desired file from the dropdown, all the layouts in your theme&amp;#39;s layout file will be available to use.&lt;/p&gt; &lt;figure
class=tutorial_image&gt;&lt;img
src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/pyrocms_layout.png" alt="Choose a layout for your PyroCMS page type" width="647" height="407"/&gt;&lt;/figure&gt;&lt;hr
/&gt;&lt;h2&gt;Mobile Layouts&lt;/h2&gt;&lt;p&gt;PyroCMS is able to easily display separate layouts for mobile and desktops. To use this feature, move your layout files into a folder, called &amp;quot;web&amp;quot; within the &lt;em&gt;views&lt;/em&gt; folder, so that your default layout will be located here:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;[your-theme]/views/web/layouts/default.html
&lt;/pre&gt;&lt;p&gt;When a user accesses your site using a desktop browser, the primary layout files in this location will be used. If the user accesses your site using a mobile device browser, users will be supplied with the mobile layouts that you&amp;#39;ve created in this location:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;[your-theme]/views/mobile/layouts/default.html
&lt;/pre&gt;&lt;p&gt;This feature works with multiple layout files.&lt;/p&gt;&lt;p&gt;Please take note of this warning found in the PyroCMS documentation: &amp;quot;PyroCMS does not consider the iPad a mobile device, so it will not load your mobile layouts if the user is accessing your site using an iPad.&amp;quot; If, however, on your site, you&amp;#39;d like to make an iPad recognized as a mobile device, you can change the &amp;quot;user_agent.php&amp;quot; file within the &lt;em&gt;config/&lt;/em&gt; directory to make the iPad recognized a mobile device.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Finished!&lt;/h2&gt;&lt;p&gt;Using this article as a guide, you can see how easy it is to create a theme in PyroCMS. The code examples provided are quite simple, so I encourage you to explore the &lt;a
href="https://www.pyrocms.com/documentation"&gt;PyroCMS documentation&lt;/a&gt; to become more experienced with &lt;a
href="http://docs.pyrocms.com/2.2/manual/guides/themes/theme-layouts"&gt;layouts&lt;/a&gt;, &lt;a
href="http://docs.pyrocms.com/2.2/manual/guides/themes/theme-layouts"&gt;mobile layouts&lt;/a&gt;, &lt;a
href="http://docs.pyrocms.com/2.2/manual/guides/themes/theme-partials"&gt;partials&lt;/a&gt;, and the &lt;a
href="http://docs.pyrocms.com/2.2/manual/guides/pyrocms-tags"&gt;Lex Parser&lt;/a&gt; in PyroCMS. Have fun!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=o44IlSNrSVQ:2SNnvSlZyAI:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=o44IlSNrSVQ:2SNnvSlZyAI:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=o44IlSNrSVQ:2SNnvSlZyAI:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=o44IlSNrSVQ:2SNnvSlZyAI:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=o44IlSNrSVQ:2SNnvSlZyAI:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=o44IlSNrSVQ:2SNnvSlZyAI:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=o44IlSNrSVQ:2SNnvSlZyAI:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=o44IlSNrSVQ:2SNnvSlZyAI:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/o44IlSNrSVQ" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/php/how-to-create-a-pyrocms-theme/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/php/how-to-create-a-pyrocms-theme/</feedburner:origLink></item> <item><title>The Linux Firewall</title><link>http://feedproxy.google.com/~r/nettuts/~3/YjnBJVTS5AU/</link> <comments>http://net.tutsplus.com/tutorials/other/the-linux-firewall/#comments</comments> <pubDate>Fri, 17 May 2013 18:00:48 +0000</pubDate> <dc:creator>Patkos Csaba</dc:creator> <category><![CDATA[Other]]></category> <category><![CDATA[linux]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31748</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31748&amp;c=871386304' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31748&amp;c=871386304' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;There are several firewall applications for Linux, but what you may not realize is that, at the heart of all these programs is a single all-mighty application that is built right into the Linux Kernel: iptables. This is the Linux firewall. No matter which program you use to configure your firewall under Linux, it ultimately all comes down to iptables. All that these other programs do is configure it.&lt;/p&gt;&lt;p&gt;So, here comes the question: if those programs simply configure iptables, why not simply configure it directly yourself? Doing so is easier than you might think!&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31748"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Networking Background&lt;/h2&gt;&lt;p&gt;If you&amp;#8217;re familiar with networking terms, like connections, IP, TCP, and Port, then feel free to skip ahead to the next step. Otherwise, if you&amp;#8217;re new to networking, read on to familiarize yourself with the terms that you will need to understand, in order to follow along with this tutorial.&lt;/p&gt;&lt;p&gt;Please note that the terms and definitions below have been intentionally over-simplified. They&amp;#8217;re meant for every-day users, not sysadmins. So if you are a seasoned sysadmin or you have a CCNA in you pocket, please excuse me for not entering into the details.&lt;br
/&gt;&lt;h3&gt;TCP/IP&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;TCP/IP&lt;/strong&gt; is a protocol that allows computers to communicate with one another over Internet and Ethernet Networks.&lt;/p&gt;&lt;blockquote
class="pullquote"&gt;&lt;p&gt; Failure is the last resort.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Imagine an &lt;strong&gt;Ethernet Network&lt;/strong&gt; as a small local network (LAN &amp;#8211; local area network), like your home PC, laptop, and smart phone. It&amp;#8217;s a small heterogeneous network that is isolated from the rest of the world. A network of such networks is what we all know as the &lt;strong&gt;Internet&lt;/strong&gt;: a set of interconnected networks.&lt;/p&gt;&lt;p&gt;TCP/IP is a combination of two protocols working at different levels in the hierarchy of the network communication chain. We won&amp;#8217;t delve into details about that hierarchy. &lt;strong&gt;TCP&lt;/strong&gt; stands for &lt;em&gt;Transfer Control Protocol&lt;/em&gt;, and its core responsibility is to ensure that communication is successful. It controls the correctness of the data sent, and ensures its success. It has different algorithms to perform sophisticated checksums, autocorrect, and retry. Failure is the last resort. The name, &lt;strong&gt;IP&lt;/strong&gt; comes from Internet Protocol. You can best associate it with the &amp;#8220;phone-number&amp;#8221; of your PC. Each machine capable of communicating over the Internet must have an IP address &amp;#8211; a unique phone number &amp;#8211; so that communication packets can find their destinations. A &lt;strong&gt;packet&lt;/strong&gt; is a small piece of data inside a communication stream, which is self contained and can be checked for correctness. Essentially, we can say that our computers send TCP packets over the Internet using the IP protocol.&lt;/p&gt;&lt;p&gt;Each network communication is bound to a specific &lt;strong&gt;port&lt;/strong&gt;. Network ports range from 0 to 2^16 (65536). Each network connection has an outgoing port for the one who initiates it, and an inbound port for the one who is listening for other computers&amp;#8217; messages. There can be several connections between several computers over identical ports. A computer can, however, talk over several ports at once. So, basically, ports are good to identify services and define channels of communications, but they do not limit the amount of data or connections.&lt;/p&gt;&lt;p&gt;Some computers can have similar IP addresses. You may have observed that both your computer at home and at work have IP addresses that takes the form of something along the lines of &lt;code&gt;192.168.something.something&lt;/code&gt;, or &lt;code&gt;10.0.something.something&lt;/code&gt;, or &lt;code&gt;172.16.something.something&lt;/code&gt;. These are the so-called private IP addresses that can be used only inside your LAN. You can&amp;#8217;t go out to the Internet with IP addresses like this. They are akin to interior numbers for your company&amp;#8217;s phone network.&lt;/p&gt;&lt;h3&gt;Gateway &amp;#038; Bridge&lt;/h3&gt;&lt;p&gt;A &lt;strong&gt;Bridge&lt;/strong&gt; is what computers with real (public) IP addresses pass to the Internet.&lt;/p&gt; &lt;figure
class=tutorial_image&gt;&lt;img
src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/bridge.png" alt="The bridge" width="600"/&gt;&lt;/figure&gt;&lt;p&gt;Essentially, these computers have the rights and capabilities to talk to one another on the Internet directly. But, since there are no direct connections between all the computers in the world (that would be quite hard to accomplish), bridges are responsible for connecting segments of the Internet.&lt;/p&gt;&lt;p&gt;Keeping our telephony analogy alive, you can imagine these bridges to be similar to the telephone centers in your town or neighborhood. If you make a call to another local number (the computers on the left in our schema), the communication could have been made directly by your telephone center by physically connecting your line with you neighbor&amp;#8217;s. However, if you instead want  to call your distant uncle Bob, your call would have to be redirected over several phone centers until your uncle&amp;#8217;s phone could be connected. These form a &lt;em&gt;bridge&lt;/em&gt; between your town and his town.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;A &lt;strong&gt;Gateway&lt;/strong&gt; is a way for computers from a private network (LAN with private IP addresses) to communicate with other computers on the Internet.&lt;/p&gt;&lt;/blockquote&gt; &lt;figure
class=tutorial_image&gt;&lt;img
src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/gateway.png" alt="Gateway" width="600"/&gt;&lt;/figure&gt;&lt;p&gt;A private network is like your company&amp;#8217;s private phone network. You can call interior numbers, but in order to call someone who is outside of your company&amp;#8217;s network &amp;#8211; like your wife at home &amp;#8211; you must first dial a special number or prefix.&lt;/p&gt;&lt;p&gt;Computers actually function in a similar way. When you are on a private network, you have a so-called gateway computer. When your computer attempts to talk to another computer on the Internet, it will &lt;em&gt;automagically&lt;/em&gt; contact the gateway first and request &amp;#8220;a line&amp;#8221; to the outside world. The gateway will do the talking to the computer found on the Internet, and will forward the message back to your computer. You, as an ordinary user, see no difference between a bridge and a gateway. Your computer will know how to deal with them.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Definition of a Firewall&lt;/h2&gt;&lt;p&gt;A firewall is a program running on a Gateway, Bridge or PC/Laptop/Smartphone that is capable of filtering incoming, outgoing, and forwarded network packets. A firewall is essentially a tool that lets you restrict you or your network&amp;#8217;s access to the Internet, and someone else&amp;#8217;s access from the Internet to your network.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;And yes, your cable router or home Wi-Fi is, in fact, a firewall for all your computers and gadgets that connect to the internet through it.&lt;/p&gt;&lt;/blockquote&gt;&lt;hr
/&gt;&lt;h2&gt;The Problem We Will Solve&lt;/h2&gt;&lt;p&gt;To set the context, let&amp;#8217;s imagine a very possible network architecture. I&amp;#8217;ve seen many small companies running something similar to this.&lt;/p&gt; &lt;figure
class=tutorial_image&gt;&lt;img
src="http://cdn.tutsplus.com/net.tutsplus.com/uploads/2013/05/network.png" alt="Network" width="600"/&gt;&lt;/figure&gt;&lt;p&gt;What we have here is actually something quite simple:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A few computers and other network-connected devices &amp;#8211; the green boxes&lt;/li&gt;&lt;li&gt;An e-mail server &amp;#8211; the red box&lt;/li&gt;&lt;li&gt;A Microsoft Active Directory server &amp;#8211; the blue box&lt;/li&gt;&lt;li&gt;A gateway, which is also a firewall, for our network running Linux &amp;#8211; the black box&lt;/li&gt;&lt;li&gt;Between all of these is a simple network switch&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In the following section, we will configure iptables on that gateway, so that it will allow all the devices in the network to connect to the Internet. It will allow us to connect to it, via SSH, and will allow external mail servers to reach the mail server inside our network &amp;#8211; a computer that does not even have a public IP address; only a private one.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Iptables Components&lt;/h2&gt;&lt;p&gt;Iptables&amp;#8217; name actually has a meaning in its functionality. It&amp;#8217;s a set of tables of IP address and ports with some actions attached to them. In iptable&amp;#8217;s terms, these tables are referred to as &lt;i&gt;chains&lt;/i&gt;. An unconfigured, empty iptables might look like this:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         &lt;/pre&gt;&lt;p&gt;You can observe that there are three main chains:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;INPUT&lt;/strong&gt; &amp;#8211; all incoming connections&lt;/li&gt;&lt;li&gt;&lt;strong&gt;FORWARD&lt;/strong&gt; &amp;#8211; connections passing through&lt;/li&gt;&lt;li&gt;&lt;strong&gt;OUTPUT&lt;/strong&gt; &amp;#8211; connections departing from this server&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The term, &amp;#8220;&lt;em&gt;policy ACCEPT&lt;/em&gt;&amp;#8221; in parenthesis means that ACCEPT is set as the default policy for that particular chain. So, when there is no match for a connection, that rule will be applied. There are three main concepts you can use when configuring your firewall:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;default policy ACCEPT &amp;#038; deny selectively all you need to&lt;/strong&gt; &amp;#8211; it may be difficult to specify all that it is denied. I do not recommend this approach.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;default policy DROP or REJECT &amp;#038; allow selectively all you need to&lt;/strong&gt; &amp;#8211; this is better, but it has a problem. If you make a mistake in your iptables configuration, you can easily remain with empty chains denying access to everything and everyone, including you. So, unless you always have physical access to your firewall server/computer, I recommend that you use the next approach.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;default policy ACCEPT &amp;#038; an explicit policy to DROP all &amp;#038; then allow selectively all you need&lt;/strong&gt; &amp;#8211; this is a combined solution between the first two possibilities. It will use an ACCEPT default policy, so if something goes wrong, you can log back over SSH or whatever remote connection you use for your firewall. At the same time, an explicit DROP rule for any unmatched connections ensures that you are safe. Allowing only what you know about and actually need to use offers the best possible protection.&lt;/li&gt;&lt;/ul&gt;&lt;hr
/&gt;&lt;h2&gt;Adding Rules to Iptables&lt;/h2&gt;&lt;p&gt;There are two ways to add a new rule to iptables. One is to insert it at the begining of a chain. The other option is to append it to the end of a chain. Why does it matter in which order the rules occur?&lt;/p&gt;&lt;div
class="tip-shortcode"&gt;&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; iptables check the rules in a chain from top to bottom. It will stop its search at the first match.&lt;/p&gt;&lt;/div&gt;&lt;p&gt;You must design your rules in such a way to consider the above mentioned behavior of iptables. After the first match of a rule, iptables will take the actions specified by the rule, and then cease the search. If no rule matches the connection that is checked, the default policy applies.&lt;/p&gt;&lt;h3&gt;Inserting a New Rule&lt;/h3&gt;&lt;p&gt;Let&amp;#8217;s say that we want to add a rule to our iptables that will allow anyone to connect to port 22 on our firewall. Port 22 is the port for the SSH protocol. Of course, a good server admin will change this port to something unexpected for obvious security/obscurity reasons, but that&amp;#8217;s another story for another tutorial. We will stick with 22.&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables -I INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
csaba ~ # iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh&lt;/pre&gt;&lt;p&gt;I presumed that the IP address facing the Internet with the public IP on it is on the network interface, called &lt;code&gt;eth0&lt;/code&gt;. Let&amp;#8217;s dissect this command:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;-&lt;strong&gt;I&lt;/strong&gt; &amp;#8211; stands for insert the rule&lt;/li&gt;&lt;li&gt; &lt;strong&gt;INPUT&lt;/strong&gt; &amp;#8211; specifies the desired chain&lt;/li&gt;&lt;li&gt; &lt;strong&gt;-i&lt;/strong&gt; &amp;#8211; stands for network interface &amp;#8211; in our case, &lt;code&gt;eth0&lt;/code&gt;&lt;/li&gt;&lt;li&gt; &lt;strong&gt;-p&lt;/strong&gt; &amp;#8211; is for protocol (tcp or udp)&lt;/li&gt;&lt;li&gt; &lt;strong&gt;&amp;#8211;dport 22&lt;/strong&gt; &amp;#8211; is for destination port 22 &amp;#8211; it has a corresponding &lt;code&gt;--sport&lt;/code&gt; version for source port verification&lt;/li&gt;&lt;li&gt; &lt;strong&gt;-j&lt;/strong&gt; &amp;#8211; actually comes from &amp;#8220;jump,&amp;#8221; and is followed by an action -in our case, the action to accept the connection&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;However, you may have already guessed that this rule has little effect at this time. Our default policy is ACCEPT, so accepting something explicitly does not offer us any extra functionality. Now, remember the third recommended way to set up our firewall: the explicit rule to deny everything not matched. Let&amp;#8217;s add that rule.&lt;/p&gt;&lt;h3&gt;Appending Rules&lt;/h3&gt;&lt;p&gt;We want to append a rule that blocks incoming traffic. But be careful: we only want to block what could be harmful. If we block everything, we will not be able to do anything, because the replies to our requests will be rejected. For example, when you browse a web page, you make a request, then you receive an answer. This answer comes into your computer, so, on the INPUT chain, we must have a rule to allow it.&lt;/p&gt;&lt;p&gt;First, we will append a rule to accept incoming traffic for already established connections, such as responses to requests.&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables -A INPUT -i eth0 -m conntrack  --ctstate ESTABLISHED,RELATED -j ACCEPT
csaba ~ # iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED&lt;/pre&gt;&lt;p&gt;Now that we&amp;#8217;ve safeguarded our existing connections and the replies to the connections we initiated, we can deny everything else that wasn&amp;#8217;t matched.&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables -A INPUT -i eth0 -p tcp -j DROP
csaba ~ # iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
DROP       tcp  --  anywhere             anywhere
&lt;/pre&gt;&lt;p&gt;We&amp;#8217;ve appended another line, with a rule to DROP all connections that match. Remember: this rule will only apply if none of the previous ones actually match.&lt;/p&gt;&lt;p&gt;There are two ways to refuse a connections.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;You can use DROP, which is equivalent to dialing a non-existent phone number with the difference that, after some time, the network connection times out. With a phone number, a robot informs you that the number does not exist. But the end result from the point of view of the caller is the same: it thinks that the destination does not exist.&lt;/p&gt;&lt;li&gt;The second way to refuse the connection is with the rule, REJECT, and an optional message. This is analogous to the number you are trying to call being busy. You may know that there is a number, you know it can be called, but it simply refuses to take your calls. Optionally, you can provide a message with a REJECT rule; the default is &amp;#8220;ICMP port unreachable&amp;#8221; or something similar.&lt;/ol&gt;&lt;hr
/&gt;&lt;h2&gt;Allow Computers to Access the Internet&lt;/h2&gt;&lt;p&gt;At this point, we have some basic rules for the INPUT chain. But we have a network of computers having private IP addresses. We need to provide a gateway to the Internet. This is also done by iptables: the firewall.&lt;/p&gt;&lt;h3&gt;Network Address Translation (NAT)&lt;/h3&gt;&lt;p&gt;Likely, you&amp;#8217;ve already heard this term: NAT. This refers to the procedure of translating one network address to another and forwarding the information between the two. It&amp;#8217;s most frequently used in architectures like our own. The gateway has to do NAT in order to translate any computer&amp;#8217;s IP from the LAN into its own public IP and then back.&lt;/p&gt;&lt;p&gt;Routing is the procedure by which a system can figure out on what network interfaces and toward what gateway it can communicate to reach its destination. Each computer has a routing table of its own to determine this. Iptables can hook into this routing procedure at two different points: before and after the procedure has occurred.&lt;/p&gt;&lt;h3&gt;Nating with Iptables&lt;/h3&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 89.72.31.243&lt;/pre&gt;&lt;p&gt;This command adds a rule as POSTROUTING to the NATing table (&lt;code&gt;-t nat&lt;/code&gt;). POSTROUTING essentially means that the packets first pass the routing mechanism on the gateway, and, only after that are they modified. The rule &lt;code&gt;-j SNAT&lt;/code&gt; means Source NAT; the source address of the packets will be changed to the address on the interface specified by &lt;code&gt;-o eth0&lt;/code&gt; &amp;#8211; in our case, to the IP address specified by the option, &lt;code&gt;--to-source&lt;/code&gt;. So, anyone contacted by a computer in your network will assume that it is talking directly to your gateway. It will have absolutely no clue about the fact that the packets are destined for some different computer. The gateway, using iptables, will keep an internal list of all the translated IP addresses, and, when a reply comes, it will revert the change and pass the answer to the computer inside the network.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Allow Client from the Internet to the Email Server&lt;/h2&gt;&lt;p&gt;Another problem that we face is what to do when we have a server that is behind a firewall. We need to allow the clients, coming from the Internet, to communicate with our server in some way. This is the case with our mail server. When an email arrives that has to be delivered to a mail account on our server, the sending email server will have to connect to our receiving one.&lt;/p&gt;&lt;p&gt;But our mail server only has a private IP address. There is no way that an external computer could connect to it directly. On the other hand, our gateway has an external IP that anyone could connect to. The solution? Open a port on our gateway so that a request from the Internet to that port will actually go to our email server. The answer, of course, will travel through the gateway back to the client. The trick is to use a different type of NAT here, called Destination NAT. This changes the packets destination and then reverts them back when the response occurs. Think of DNAT as the reverse of SNAT.&lt;/p&gt;&lt;div
class="tip-shortcode"&gt;&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; You may know this feature as &amp;#8220;Virtual Server,&amp;#8221; if you&amp;#8217;ve ever played around with small home routers.&lt;/p&gt;&lt;/div&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 25 -j DNAT --to-destination 192.168.1.2:25&lt;/pre&gt;&lt;p&gt;So, what is happening here? A packet comes in to our gateway at the port 25 (the port used for SMTP, the email protocol the whole Internet uses). The rule above catches this packet because of the &lt;code&gt;--dport 25&lt;/code&gt; option, which basically says, &amp;#8220;&lt;em&gt;Match anything that goes to this port on the interface specified by &lt;code&gt;-i eth0&lt;/code&gt;. Now that the packet is matched, change its destination from the current machine (the gateway) to the one specified by &lt;code&gt;--to-destination&lt;/code&gt;.&lt;/em&gt;&amp;#8221; Please note that you can specify the port explicitly after the IP address by separating it with a colon.&lt;/p&gt;&lt;p&gt;Finally, note that this is in the PREROUTING hook. The destination has to be changed before the routing actually takes place. Otherwise, the packets would end up on the gateway and find no way to the mail server.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Persisting iptables Configuration&lt;/h2&gt;&lt;p&gt;The rules you insert or append to iptables are in memory. After a reboot, spoof: everything is gone! To save your configuration, you should dump it into a file, like so:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;csaba ~ # iptables-save &amp;gt; /some/directory/my_rules.fw&lt;/pre&gt;&lt;p&gt;The file&amp;#8217;s name doesn&amp;#8217;t matter, nor does its extension. To restore the rules, run this command when your computer starts.&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;iptables-restor &amp;lt; /some/directory/my_rules.fw&lt;/pre&gt;&lt;p&gt;If you take a look at the saved content, you&amp;#8217;ll see that they&amp;#8217;re the same parameters that we used with the iptables commands. There are some minor differences, but you can easily understand the saved file, and could even write your own such files by hand and load them.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Final Thoughts&lt;/h2&gt;&lt;p&gt;In closing, here are some thoughts on when and when not to use a firewall with a Linux computer.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Use a firewall&lt;/strong&gt; on Linux when you configure a server (like a gateway in our example), or when you have a computer with important information on it that is directly exposed to the Internet. Before you jump on to configure your iptables, consider the potential danger. Ask yourself: is my computer known on the Internet? There are a few billion computers out there. If yours is just one, the chance of being targeted is incredibly low. Are there people directly interested in your information? Hackers don&amp;#8217;t waste time stealing random data in the hopes that they might find something. They usually know what they are looking for, and then target the computers containing the desired information. Of course, there are countless attacks against random computers that attempt to install some kind of worm or virus, but on Linux, you are immune by design.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Don&amp;#8217;t waste your time&lt;/strong&gt; with configuring a firewall on Linux when it is a computer that is alway behind a firewall, such as your home PC behind your home router, or when you have no particularly important information on your laptop. If you keep the services that listen on the network to a minimum and have a decently secure password, you can forget your firewall. I personally have no personal computer, laptop or smartphone with a firewall running. I have, however, a home router with a well-configured firewall.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;I think you can safely apply these ideas to Mac OSX as well. If you&amp;#8217;re a Windows user, sorry: a firewall is your first line of defense. For Linux or MacOSX, though, a firewall is your last line of defense. A  carefully selected password and not running useless services should handle the bulk of your computer&amp;#8217;s protection.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Thanks for reading. Questions?&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=YjnBJVTS5AU:G3Xi0DKl-7M:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=YjnBJVTS5AU:G3Xi0DKl-7M:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=YjnBJVTS5AU:G3Xi0DKl-7M:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=YjnBJVTS5AU:G3Xi0DKl-7M:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=YjnBJVTS5AU:G3Xi0DKl-7M:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=YjnBJVTS5AU:G3Xi0DKl-7M:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=YjnBJVTS5AU:G3Xi0DKl-7M:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=YjnBJVTS5AU:G3Xi0DKl-7M:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/YjnBJVTS5AU" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/other/the-linux-firewall/feed/</wfw:commentRss> <slash:comments>16</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/other/the-linux-firewall/</feedburner:origLink></item> <item><title>Tuts+ Premium Cash Back Offer: 3 Days to Go</title><link>http://feedproxy.google.com/~r/nettuts/~3/mH16lMPEuDo/</link> <comments>http://net.tutsplus.com/articles/news/tuts-premium-cash-back-offer-3-days-to-go/#comments</comments> <pubDate>Fri, 17 May 2013 17:00:56 +0000</pubDate> <dc:creator>Joel Bankhead</dc:creator> <category><![CDATA[News]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31722</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31722&amp;c=1320947298' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31722&amp;c=1320947298' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;&lt;strong&gt;This offer ends soon! Act now and don’t miss out on cash back when trying a monthly Tuts+ Premium subscription.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;At $19 a month, Tuts+ Premium is fantastic value. But it&amp;#8217;s even better when we hand your first $19 right back to you!&lt;/p&gt;&lt;p&gt;For a limited time, we&amp;#8217;re offering $19 cash back to new Tuts+ Premium monthly subscribers when signing up via PayPal. If you’ve been thinking about checking out our extensive library of courses, tutorials, eBooks and guides there’s never been a better time to join up and dive in.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;This offer ends at noon on the 20th of May AEST, so act fast.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;a
href="https://tutsplus.com/paypal-cash-back-offer/?utm_source=nettutsend&amp;#038;utm_medium=post&amp;#038;utm_campaign=paypal_cashback&amp;#038;wt.mc_id=paypal"&gt;Become a Tuts+ Premium Member and take your creative &amp;#038; technical skills to a new level.&lt;/a&gt;&lt;br
/&gt; &lt;span
id="more-31722"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt; What can you learn on Tuts+ Premium? Glad you asked! Currently, more than 15,000 members are sharpening their skills in a wide range of areas including web design, web development, Photoshop, vectors, video effects, and many more. With Tuts+ Premium you learn from expert instructors in every field.&lt;/p&gt;&lt;p&gt;Join now and get instant access to your very own library of courses, tutorials, and eBooks, available whenever you need them. Become part of a community of over 15,000 members and start getting better at the skills you care about. Our dedicated team adds new content weekly, so there&amp;#8217;s always something fresh to sink your teeth into.&lt;/p&gt;&lt;p&gt;&lt;a
href="https://tutsplus.com/paypal-cash-back-offer/?utm_source=nettutsend&amp;#038;utm_medium=post&amp;#038;utm_campaign=paypal_cashback&amp;#038;wt.mc_id=paypal"&gt;Join Tuts+ Premium&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=mH16lMPEuDo:yBmtqhdwOjQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=mH16lMPEuDo:yBmtqhdwOjQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=mH16lMPEuDo:yBmtqhdwOjQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=mH16lMPEuDo:yBmtqhdwOjQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=mH16lMPEuDo:yBmtqhdwOjQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=mH16lMPEuDo:yBmtqhdwOjQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=mH16lMPEuDo:yBmtqhdwOjQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=mH16lMPEuDo:yBmtqhdwOjQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/mH16lMPEuDo" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/articles/news/tuts-premium-cash-back-offer-3-days-to-go/feed/</wfw:commentRss> <slash:comments>3</slash:comments> <feedburner:origLink>http://net.tutsplus.com/articles/news/tuts-premium-cash-back-offer-3-days-to-go/</feedburner:origLink></item> <item><title>How to Write Testable and Maintainable Code in PHP</title><link>http://feedproxy.google.com/~r/nettuts/~3/l6VzPp300us/</link> <comments>http://net.tutsplus.com/tutorials/php/how-to-write-testable-and-maintainable-code-in-php/#comments</comments> <pubDate>Wed, 15 May 2013 20:08:11 +0000</pubDate> <dc:creator>Chris Fidao</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[tdd]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31726</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31726&amp;c=325420048' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31726&amp;c=325420048' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;Frameworks provide a tool for rapid application development, but often accrue technical debt as rapidly as they allow you to create functionality. Technical debt is created when maintainability isn&amp;#39;t a purposeful focus of the developer. Future changes and debugging become costly, due to a lack of unit testing and structure.&lt;/p&gt;&lt;p&gt;Here&amp;#39;s how to begin structuring your code to achieve testability and maintainability &amp;#8211; and save you time.&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31726"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;We&amp;#39;ll Cover (loosely)&lt;/h2&gt;&lt;ol&gt;&lt;li&gt;DRY&lt;/li&gt;&lt;li&gt;Dependency Injection&lt;/li&gt;&lt;li&gt;Interfaces&lt;/li&gt;&lt;li&gt;Containers&lt;/li&gt;&lt;li&gt;Unit Tests with PHPUnit&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Let&amp;#39;s begin with some contrived, but typical code. This might be a model class in any given framework.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
class User {

public function getCurrentUser()
{
    $user_id = $_SESSION['user_id'];

    $user = App::db-&amp;gt;select('id, username')
                    -&amp;gt;where('id', $user_id)
                    -&amp;gt;limit(1)
                    -&amp;gt;get();

    if ( $user-&amp;gt;num_results() &amp;gt; 0 )
    {
            return $user-&amp;gt;row();
    }

    return false;
}

}
&lt;/pre&gt;&lt;p&gt;This code will work, but needs improvement:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;This isn&amp;#39;t testable.&lt;ul&gt;&lt;li&gt;We&amp;#39;re relying on the &lt;code&gt;$_SESSION&lt;/code&gt; global variable. Unit-testing frameworks, such as PHPUnit, rely on the command-line, where &lt;code&gt;$_SESSION&lt;/code&gt; and many other global variables aren&amp;#39;t available.&lt;/li&gt;&lt;li&gt;We&amp;#39;re relying on the database connection. Ideally, actual database connections should be avoided in a unit-test. Testing is about code, not about data.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;This code isn&amp;#39;t as maintainable as it could be. For instance, if we change the data source, we&amp;#39;ll need to change the database code in every instance of &lt;code&gt;App::db&lt;/code&gt; used in our application. Also, what about instances where we don&amp;#39;t want just the current user&amp;#39;s information?&lt;/li&gt;&lt;/ol&gt;&lt;h4&gt;An Attempted Unit Test&lt;/h4&gt;&lt;p&gt;Here&amp;#39;s an attempt to create a unit test for the above functionality.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
class UserModelTest extends PHPUnit_Framework_TestCase {

    public function testGetUser()
    {
        $user = new User();

        $currentUser = $user-&amp;gt;getCurrentUser();

        $this-&amp;gt;assertEquals(1, $currentUser-&amp;gt;id);
    }

}
&lt;/pre&gt;&lt;p&gt;Let&amp;#39;s examine this. First, the test will fail. The &lt;code&gt;$_SESSION&lt;/code&gt; variable used in the &lt;code&gt;User&lt;/code&gt; object doesn&amp;#39;t exist in a unit test, as it runs PHP in the command line.&lt;/p&gt;&lt;p&gt;Second, there&amp;#39;s no database connection setup. This means that, in order to make this work, we will need to bootstrap our application in order to get the &lt;code&gt;App&lt;/code&gt; object and its &lt;code&gt;db&lt;/code&gt; object. We&amp;#39;ll also need a working database connection to test against.&lt;/p&gt;&lt;p&gt;To make this unit test work, we would need to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Setup a config setup for a CLI (PHPUnit) run in our application&lt;/li&gt;&lt;li&gt;Rely on a database connection. Doing this means relying on a data source separate from our unit test. What if our test database doesn&amp;#39;t have the data we&amp;#39;re expecting? What if our database connection is slow?&lt;/li&gt;&lt;li&gt;Relying on an application being bootstrapped increases the overhead of the tests, slowing the unit tests down dramatically. Ideally, most of our code can be tested independent of the framework being used.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So, let&amp;#39;s get down to how we can improve this.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Keep Code DRY&lt;/h2&gt;&lt;p&gt;The function retrieving the current user is unnecessary in this simple context. This is a contrived example, but in the spirit of DRY principles, the first optimization I&amp;#39;m choosing to make is to generalize this method.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
class User {

    public function getUser($user_id)
    {
        $user = App::db-&amp;gt;select('user')
                        -&amp;gt;where('id', $user_id)
                        -&amp;gt;limit(1)
                        -&amp;gt;get();

        if ( $user-&amp;gt;num_results() &amp;gt; 0 )
        {
            return $user-&amp;gt;row();
        }

        return false;
    }

}
&lt;/pre&gt;&lt;p&gt;This provides a method we can use across our entire application. We can pass in the current user at the time of the call, rather than passing that functionality off to the model. Code is more modular and maintainable when it doesn&amp;#39;t rely on other functionalities (such as the session global variable).&lt;/p&gt;&lt;p&gt;However, this is still not testable and maintainable as it could be. We&amp;#39;re still relying on the database connection.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Dependency Injection&lt;/h2&gt;&lt;p&gt;Let&amp;#39;s help improve the situation by adding some Dependency Injection. Here&amp;#39;s what our model might look like, when we pass the database connnection into the class.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
class User {

    protected $_db;

    public function __construct($db_connection)
    {
        $this-&amp;gt;_db = $db_connection;
    }

    public function getUser($user_id)
    {
        $user = $this-&amp;gt;_db-&amp;gt;select('user')
                        -&amp;gt;where('id', $user_id)
                        -&amp;gt;limit(1)
                        -&amp;gt;get();

        if ( $user-&amp;gt;num_results() &amp;gt; 0 )
        {
            return $user-&amp;gt;row();
        }

        return false;
    }

}
&lt;/pre&gt;&lt;p&gt;Now, the dependencies of our &lt;code&gt;User&lt;/code&gt; model are provided for. Our class no longer assumes a certain database connection, nor relies on any global objects.&lt;/p&gt;&lt;p&gt;At this point, our class is basically testable. We can pass in a data-source of our choice (mostly) and a user id, and test the results of that call. We can also switch out separate database connections (assuming that both implement the same methods for retrieving data). Cool.&lt;/p&gt;&lt;p&gt;Let&amp;#39;s look at what a unit test might look like for that.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
&amp;lt;?php

use Mockery as m;
use Fideloper\User;

class SecondUserTest extends PHPUnit_Framework_TestCase {

    public function testGetCurrentUserMock()
    {
        $db_connection = $this-&amp;gt;_mockDb();

        $user = new User( $db_connection );

        $result = $user-&amp;gt;getUser( 1 );

        $expected = new StdClass();
        $expected-&amp;gt;id = 1;
        $expected-&amp;gt;username = 'fideloper';

        $this-&amp;gt;assertEquals( $result-&amp;gt;id, $expected-&amp;gt;id, 'User ID set correctly' );
        $this-&amp;gt;assertEquals( $result-&amp;gt;username, $expected-&amp;gt;username, 'Username set correctly' );
    }

    protected function _mockDb()
    {
        // &amp;quot;Mock&amp;quot; (stub) database row result object
        $returnResult = new StdClass();
        $returnResult-&amp;gt;id = 1;
        $returnResult-&amp;gt;username = 'fideloper';

        // Mock database result object
        $result = m::mock('DbResult');
        $result-&amp;gt;shouldReceive('num_results')-&amp;gt;once()-&amp;gt;andReturn( 1 );
        $result-&amp;gt;shouldReceive('row')-&amp;gt;once()-&amp;gt;andReturn( $returnResult );

        // Mock database connection object
        $db = m::mock('DbConnection');

        $db-&amp;gt;shouldReceive('select')-&amp;gt;once()-&amp;gt;andReturn( $db );
        $db-&amp;gt;shouldReceive('where')-&amp;gt;once()-&amp;gt;andReturn( $db );
        $db-&amp;gt;shouldReceive('limit')-&amp;gt;once()-&amp;gt;andReturn( $db );
        $db-&amp;gt;shouldReceive('get')-&amp;gt;once()-&amp;gt;andReturn( $result );

        return $db;
    }

}
&lt;/pre&gt;&lt;p&gt;I&amp;#39;ve added something new to this unit test: Mockery. Mockery lets you &amp;quot;mock&amp;quot; (fake) PHP objects. In this case, we&amp;#39;re mocking the database connection. With our mock, we can skip over testing a database connection and simply test our model.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Want to &lt;a
href="http://net.tutsplus.com/tutorials/php/mockery-a-better-way/"&gt;learn more about Mockery&lt;/a&gt;?&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;In this case, we&amp;#39;re mocking a SQL connection. We&amp;#39;re telling the mock object to expect to have the &lt;code&gt;select&lt;/code&gt;, &lt;code&gt;where&lt;/code&gt;, &lt;code&gt;limit&lt;/code&gt; and &lt;code&gt;get&lt;/code&gt; methods called on it. I am returning the Mock, itself, to mirror how the SQL connection object returns itself (&lt;code&gt;$this&lt;/code&gt;), thus making its method calls &amp;quot;chainable&amp;quot;. Note that, for the &lt;code&gt;get&lt;/code&gt; method, I return the database call result &amp;#8211; a &lt;code&gt;stdClass&lt;/code&gt; object with the user data populated.&lt;/p&gt;&lt;p&gt;This solves a few problems:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;We&amp;#39;re testing only our model class. We&amp;#39;re not also testing a database connection.&lt;/li&gt;&lt;li&gt;We&amp;#39;re able to control the inputs and outputs of the mock database connection, and, therefore, can reliably test against the result of the database call. I know I&amp;#39;ll get a user ID of &amp;quot;1&amp;quot; as a result of the mocked database call.&lt;/li&gt;&lt;li&gt;We don&amp;#39;t need to bootstrap our application or have any configuration or database present to test.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;We can still do much better. Here&amp;#39;s where it gets interesting.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Interfaces&lt;/h2&gt;&lt;p&gt;To improve this further, we could define and implement an interface. Consider the following code.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
interface UserRepositoryInterface {
    public function getUser($user_id);
}

class MysqlUserRepository implements UserRepositoryInterface {

    protected $_db;

    public function __construct($db_conn)
    {
        $this-&amp;gt;_db = $db_conn;
    }

    public function getUser($user_id)
    {
        $user = $this-&amp;gt;_db-&amp;gt;select('user')
                    -&amp;gt;where('id', $user_id)
                    -&amp;gt;limit(1)
                    -&amp;gt;get();

        if ( $user-&amp;gt;num_results() &amp;gt; 0 )
        {
            return $user-&amp;gt;row();
        }

        return false;
    }

}

class User {

    protected $userStore;

    public function __construct(UserRepositoryInterface $user)
    {
        $this-&amp;gt;userStore = $user;
    }

    public function getUser($user_id)
    {
        return $this-&amp;gt;userStore-&amp;gt;getUser($user_id);
    }

}
&lt;/pre&gt;&lt;p&gt;There&amp;#39;s a few things happening here.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;First, we define an interface for our user &lt;em&gt;data source&lt;/em&gt;. This defines the &lt;code&gt;addUser()&lt;/code&gt; method.&lt;/li&gt;&lt;li&gt;Next, we implement that interface. In this case, we create a MySQL implementation. We accept a database connection object, and use it to grab a user from the database.&lt;/li&gt;&lt;li&gt;Lastly, we enforce the use of a class implementing the &lt;code&gt;UserInterface&lt;/code&gt; in our &lt;code&gt;User&lt;/code&gt; model. This guarantees that the data source will always have a &lt;code&gt;getUser()&lt;/code&gt; method available, no matter which data source is used to implement &lt;code&gt;UserInterface&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;blockquote&gt;&lt;p&gt;Note that our &lt;code&gt;User&lt;/code&gt; object type-hints &lt;code&gt;UserInterface&lt;/code&gt; in its constructor. This means that a class implementing &lt;code&gt;UserInterface&lt;/code&gt; MUST be passed into the &lt;code&gt;User&lt;/code&gt; object. This is a guarantee we are relying on &amp;#8211; we need the &lt;code&gt;getUser&lt;/code&gt; method to always be available.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;What is the result of this?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Our code is now &lt;em&gt;fully&lt;/em&gt; testable. For the &lt;code&gt;User&lt;/code&gt; class, we can easily mock the data source. (Testing the implementations of the datasource would be the job of a separate unit test).&lt;/li&gt;&lt;li&gt;Our code is &lt;em&gt;much&lt;/em&gt; more maintainable. We can switch out different data sources without having to change code throughout our application.&lt;/li&gt;&lt;li&gt;We can create &lt;em&gt;ANY&lt;/em&gt; data source. ArrayUser, MongoDbUser, CouchDbUser, MemoryUser, etc.&lt;/li&gt;&lt;li&gt;We can easily pass any data source to our &lt;code&gt;User&lt;/code&gt; object if we need to.  If you decide to ditch SQL, you can just create a different implementation (for instance, &lt;code&gt;MongoDbUser&lt;/code&gt;) and pass that into your &lt;code&gt;User&lt;/code&gt; model.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;We&amp;#39;ve simplified our unit test, as well!&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
&amp;lt;?php

use Mockery as m;
use Fideloper\User;

class ThirdUserTest extends PHPUnit_Framework_TestCase {

    public function testGetCurrentUserMock()
    {
        $userRepo = $this-&amp;gt;_mockUserRepo();

        $user = new User( $userRepo );

        $result = $user-&amp;gt;getUser( 1 );

        $expected = new StdClass();
        $expected-&amp;gt;id = 1;
        $expected-&amp;gt;username = 'fideloper';

        $this-&amp;gt;assertEquals( $result-&amp;gt;id, $expected-&amp;gt;id, 'User ID set correctly' );
        $this-&amp;gt;assertEquals( $result-&amp;gt;username, $expected-&amp;gt;username, 'Username set correctly' );
    }

    protected function _mockUserRepo()
    {
        // Mock expected result
        $result = new StdClass();
        $result-&amp;gt;id = 1;
        $result-&amp;gt;username = 'fideloper';

        // Mock any user repository
        $userRepo = m::mock('Fideloper\Third\Repository\UserRepositoryInterface');
        $userRepo-&amp;gt;shouldReceive('getUser')-&amp;gt;once()-&amp;gt;andReturn( $result );

        return $userRepo;
    }

}
&lt;/pre&gt;&lt;p&gt;We&amp;#39;ve taken the work of mocking a database connection out completely. Instead, we simply mock the data source, and tell it what to do when &lt;code&gt;getUser&lt;/code&gt; is called.&lt;/p&gt;&lt;p&gt;But, we can still do better!&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Containers&lt;/h2&gt;&lt;p&gt;Consider the usage of our current code:&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
// In some controller
$user = new User( new MysqlUser( App:db-&amp;gt;getConnection(&amp;quot;mysql&amp;quot;) ) );
$user-&amp;gt;id = App::session(&amp;quot;user-&amp;gt;id&amp;quot;);

$currentUser = $user-&amp;gt;getUser($user_id);
&lt;/pre&gt;&lt;p&gt;Our final step will be to introduce &lt;em&gt;containers&lt;/em&gt;. In the above code, we need to create and use a bunch of objects just to get our current user. This code might be littered across your application. If you need to switch from MySQL to MongoDB, you&amp;#39;ll &lt;em&gt;still&lt;/em&gt; need to edit every place where the above code appears. That&amp;#39;s hardly DRY. &lt;a
href="http://pimple.sensiolabs.org/"&gt;Containers&lt;/a&gt; can fix this.&lt;/p&gt;&lt;p&gt;A container simply &amp;quot;contains&amp;quot; an object or functionality. It&amp;#39;s similar to a registry in your application. We can use a container to automatically instantiate a new &lt;code&gt;User&lt;/code&gt; object with all needed dependencies. Below, I use &lt;a
href="http://pimple.sensiolabs.org/"&gt;Pimple&lt;/a&gt;, a popular container class.&lt;/p&gt;&lt;pre class="brush: php; title: ; notranslate"&gt;
// Somewhere in a configuration file
$container = new Pimple();
$container[&amp;quot;user&amp;quot;] = function() {
    return new User( new MysqlUser( App:db-&amp;gt;getConnection('mysql') ) );
}

// Now, in all of our controllers, we can simply write:
$currentUser = $container['user']-&amp;gt;getUser( App::session('user_id') );
&lt;/pre&gt;&lt;p&gt;I&amp;#39;ve moved the creation of the &lt;code&gt;User&lt;/code&gt; model into one location in the application configuration. As a result:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;We&amp;#39;ve kept our code DRY. The &lt;code&gt;User&lt;/code&gt; object and the data store of choice is defined in one location in our application.&lt;/li&gt;&lt;li&gt;We can switch out our &lt;code&gt;User&lt;/code&gt; model from using MySQL to any other data source in &lt;strong&gt;ONE&lt;/strong&gt; location. This is vastly more maintainable.&lt;/li&gt;&lt;/ol&gt;&lt;hr
/&gt;&lt;h2&gt;Final Thoughts&lt;/h2&gt;&lt;p&gt;Over the course of this tutorial, we accomplished the following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Kept our code DRY and reusable&lt;/li&gt;&lt;li&gt;Created maintainable code &amp;#8211; We can switch out data sources for our objects in one location for the entire application if needed&lt;/li&gt;&lt;li&gt;Made our code testable &amp;#8211; We can mock objects easily without relying on bootstrapping our application or creating a test database&lt;/li&gt;&lt;li&gt;Learned about using Dependency Injection and Interfaces, in order to enable creating testable and maintainable code&lt;/li&gt;&lt;li&gt;Saw how containers can aid in making our application more maintainable&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I&amp;#39;m sure you&amp;#39;ve noticed that we&amp;#39;ve added much more code in the name of maintainability and testability. A strong argument can be made against this implementation: we&amp;#39;re increasing complexity. Indeed, this requires a deeper knowledge of code, both for the main author and for collaborators of a project.&lt;/p&gt;&lt;p&gt;However, the cost of explanation and understanding is far out-weighed by the extra overall &lt;em&gt;decrease&lt;/em&gt; in technical debt.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The code is vastly more maintainable, making changes possible in one location, rather than several.&lt;/li&gt;&lt;li&gt;Being able to unit test (quickly) will reduce bugs in code by a large margin &amp;#8211; especially in long-term or community-driven (open-source) projects.&lt;/li&gt;&lt;li&gt;Doing the extra-work up front &lt;em&gt;will&lt;/em&gt; save time and headache later.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Resources&lt;/h3&gt;&lt;p&gt;You may include &lt;strong&gt;Mockery&lt;/strong&gt; and &lt;strong&gt;PHPUnit&lt;/strong&gt; into your application easily using &lt;a
href="http://getcomposer.org/"&gt;Composer&lt;/a&gt;. Add these to your &amp;quot;require-dev&amp;quot; section in your &lt;code&gt;composer.json&lt;/code&gt; file:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;
&amp;quot;require-dev&amp;quot;: {
    &amp;quot;mockery/mockery&amp;quot;: &amp;quot;0.8.*&amp;quot;,
    &amp;quot;phpunit/phpunit&amp;quot;: &amp;quot;3.7.*&amp;quot;
}
&lt;/pre&gt;&lt;p&gt;You can then install your Composer-based dependencies with the &amp;quot;dev&amp;quot; requirements:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;
$ php composer.phar install --dev
&lt;/pre&gt;&lt;p&gt;Learn more about Mockery, Composer and PHPUnit here on Nettuts+.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a
href="http://net.tutsplus.com/tutorials/php/mockery-a-better-way/"&gt;Mockery: A Better Way&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://net.tutsplus.com/tutorials/php/easy-package-management-with-composer/"&gt;Easy Package Management With Composer&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href="http://net.tutsplus.com/sessions/test-driven-php/"&gt;Test-Driven PHP&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;For PHP, consider using Laravel 4, as it makes exceptional use of &lt;a
href="http://four.laravel.com/docs/ioc"&gt;containers&lt;/a&gt; and other concepts written about here.&lt;/p&gt;&lt;p&gt;Thanks for reading!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=l6VzPp300us:W9HQQhbY1HM:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=l6VzPp300us:W9HQQhbY1HM:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=l6VzPp300us:W9HQQhbY1HM:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=l6VzPp300us:W9HQQhbY1HM:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=l6VzPp300us:W9HQQhbY1HM:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=l6VzPp300us:W9HQQhbY1HM:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=l6VzPp300us:W9HQQhbY1HM:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=l6VzPp300us:W9HQQhbY1HM:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/l6VzPp300us" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/php/how-to-write-testable-and-maintainable-code-in-php/feed/</wfw:commentRss> <slash:comments>33</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/php/how-to-write-testable-and-maintainable-code-in-php/</feedburner:origLink></item> <item><title>Real Time Chat With NodeJS, Socket.io and ExpressJS</title><link>http://feedproxy.google.com/~r/nettuts/~3/eOVTqZbxzsA/</link> <comments>http://net.tutsplus.com/tutorials/javascript-ajax/real-time-chat-with-nodejs-socket-io-and-expressjs/#comments</comments> <pubDate>Tue, 14 May 2013 17:57:14 +0000</pubDate> <dc:creator>Krasimir Tsonev</dc:creator> <category><![CDATA[JavaScript & AJAX]]></category> <category><![CDATA[expressjs]]></category> <category><![CDATA[nodejs]]></category> <category><![CDATA[socket.io]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31708</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31708&amp;c=894044144' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31708&amp;c=894044144' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;&lt;a
href="http://nodejs.org/"&gt;NodeJS&lt;/a&gt; gives me the ability to write back-end code in one of my favorite languages: JavaScript. It&amp;#39;s the perfect technology for building real time applications. In this tutorial, I&amp;#39;ll show you how to build a web chat application, using ExpressJS and &lt;a
href="http://socket.io/"&gt;Socket.io&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31708"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Setup Environment&lt;/h2&gt;&lt;p&gt;Of course, the first thing to do is get &lt;a
href="http://nodejs.org/"&gt;NodeJS&lt;/a&gt; installed on your system. If you are a Windows or Mac user, you can visit &lt;a
href="http://nodejs.org/download/"&gt;nodejs.org&lt;/a&gt; and download the installer. If you instead prefer Linux, I&amp;#39;d suggest that you refer to this &lt;a
href="https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager"&gt;link&lt;/a&gt;. Although I won&amp;#8217;t go into further details on this, if you encounter any installation issues, I&amp;#8217;m happy to help; just leave a comment below this post.&lt;/p&gt;&lt;p&gt;Once you have NodeJS installed, you&amp;#8217;re ready to setup the needed instruments.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a
href="http://expressjs.com/"&gt;ExpressJS&lt;/a&gt; &amp;#8211; this will manage the server and the response to the user&lt;/li&gt;&lt;li&gt;&lt;a
href="http://jade-lang.com/"&gt;Jade&lt;/a&gt; &amp;#8211; template engine&lt;/li&gt;&lt;li&gt;&lt;a
href="http://socket.io/"&gt;Socket.io&lt;/a&gt; &amp;#8211; allows for real time communication between the front-end and back-end&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Continuing on, within an empty directory, create a &lt;em&gt;package.json&lt;/em&gt; file with the following content.&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;{
    &amp;quot;name&amp;quot;: &amp;quot;RealTimeWebChat&amp;quot;,
    &amp;quot;version&amp;quot;: &amp;quot;0.0.0&amp;quot;,
    &amp;quot;description&amp;quot;: &amp;quot;Real time web chat&amp;quot;,
    &amp;quot;dependencies&amp;quot;: {
        &amp;quot;socket.io&amp;quot;: &amp;quot;latest&amp;quot;,
        &amp;quot;express&amp;quot;: &amp;quot;latest&amp;quot;,
        &amp;quot;jade&amp;quot;: &amp;quot;latest&amp;quot;
    },
    &amp;quot;author&amp;quot;: &amp;quot;developer&amp;quot;
}
&lt;/pre&gt;&lt;p&gt;By using the console (under Windows &amp;#8211; command prompt), navigate to your folder and execute:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;npm install
&lt;/pre&gt;&lt;p&gt;Within a few seconds, you&amp;#8217;ll have all the necessary dependencies downloaded to the &lt;em&gt;node_modules&lt;/em&gt; directory.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Developing the Backend&lt;/h2&gt;&lt;p&gt;Let&amp;#8217;s begin with a simple server, which will deliver the application&amp;#39;s HTML page, and then continue with the more interesting bits: the real time communication. Create an &lt;em&gt;index.js&lt;/em&gt; file with the following core &lt;a
href="http://expressjs.com/"&gt;expressjs&lt;/a&gt; code:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;var express = require(&amp;quot;express&amp;quot;);
var app = express();
var port = 3700;

app.get(&amp;quot;/&amp;quot;, function(req, res){
    res.send(&amp;quot;It works!&amp;quot;);
});

app.listen(port);
console.log(&amp;quot;Listening on port &amp;quot; + port);
&lt;/pre&gt;&lt;p&gt;Above, we&amp;#8217;ve created an application and defined its port. Next, we registered a route, which, in this case, is a simple GET request without any parameters. For now, the route&amp;#8217;s handler simply sends some text to the client. Finally, of course, at the bottom, we run the server. To initialize the application, from the console, execute:&lt;/p&gt;&lt;pre class="brush: bash; title: ; notranslate"&gt;node index.js
&lt;/pre&gt;&lt;p&gt;The server is running, so you should be able to open &lt;em&gt;http://127.0.0.1:3700/&lt;/em&gt; and see:&lt;/p&gt;&lt;pre class="brush: plain; title: ; notranslate"&gt;It works!
&lt;/pre&gt;&lt;p&gt;Now, instead of &lt;em&gt;&amp;quot;It works&amp;quot;&lt;/em&gt; we should serve HTML. Instead of pure HTML, it can be beneficial  to use a template engine. &lt;a
href="http://jade-lang.com/"&gt;Jade&lt;/a&gt; is an excellent choice, which has good integration with ExpressJS. This is what I typically use in my own projects. Create a directory, called &lt;em&gt;tpl&lt;/em&gt;, and put the following &lt;em&gt;page.jade&lt;/em&gt; file within it:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;!!!
html
    head
        title= &amp;quot;Real time web chat&amp;quot;
    body
        #content(style='width: 500px; height: 300px; margin: 0 0 20px 0; border: solid 1px #999; overflow-y: scroll;')
        .controls
            input.field(style='width:350px;')
            input.send(type='button', value='send')
&lt;/pre&gt;&lt;p&gt;The Jade&amp;#39;s syntax is not so complex, but, for a full guide, I suggest that you refer to &lt;a
href="http://jade-lang.com/"&gt;jade-lang.com&lt;/a&gt;. In order to use Jade with ExpressJS, we require the following settings.&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;app.set('views', __dirname + '/tpl');
app.set('view engine', &amp;quot;jade&amp;quot;);
app.engine('jade', require('jade').__express);
app.get(&amp;quot;/&amp;quot;, function(req, res){
    res.render(&amp;quot;page&amp;quot;);
});
&lt;/pre&gt;&lt;p&gt;This code informs Express where your template files are, and which template engine to use. It all specifies the function that will process the template&amp;#39;s code. Once everything is setup, we can use the &lt;code&gt;.render&lt;/code&gt; method of the &lt;code&gt;response&lt;/code&gt; object, and simply send our Jade code to the user.&lt;/p&gt;&lt;p&gt; The output isn&amp;#8217;t special at this point; nothing more than a &lt;code&gt;div&lt;/code&gt; element (the one with id &lt;code&gt;content&lt;/code&gt;), which will be used as a holder for the chat messages and two controls (input field and button), which we will use to send the message.&lt;/p&gt;&lt;p&gt;Because we will use an external JavaScript file that will hold the front-end logic, we need to inform ExpressJS where to look for such resources. Create an empty directory, &lt;code&gt;public&lt;/code&gt;, and add the following line before the call to the &lt;code&gt;.listen&lt;/code&gt; method.&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;app.use(express.static(__dirname + '/public'));
&lt;/pre&gt;&lt;p&gt;So far so good; we have a server that successfully responds to GET requests. Now, it&amp;#8217;s time to add &lt;em&gt;Socket.io&lt;/em&gt; integration. Change this line:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;app.listen(port);
&lt;/pre&gt;&lt;p&gt;to:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;var io = require('socket.io').listen(app.listen(port));
&lt;/pre&gt;&lt;p&gt;Above, we passed the ExpressJS server to Socket.io. In effect, our real time communication will still happen on the same port.&lt;/p&gt;&lt;p&gt;Moving forward, we need to write the code that will receive a message from the client, and send it to all the others. Every Socket.io application begins with a &lt;code&gt;connection&lt;/code&gt; handler. We should have one:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;io.sockets.on('connection', function (socket) {
    socket.emit('message', { message: 'welcome to the chat' });
    socket.on('send', function (data) {
        io.sockets.emit('message', data);
    });
});
&lt;/pre&gt;&lt;p&gt;The object, &lt;code&gt;socket&lt;/code&gt;, which is passed to your handler, is actually the socket of the client. Think about it as a junction between your server and the user&amp;#39;s browser. Upon a successful connection, we send a &lt;code&gt;welcome&lt;/code&gt; type of message, and, of course, bind another handler that will be used as a receiver. As a result, the client should emit a message with the name, &lt;code&gt;send&lt;/code&gt;, which we will catch. Following that, we  simply forward the data sent by the user to all other sockets with &lt;code&gt;io.sockets.emit&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;With the code above, our back-end is ready to receive and send messages to the clients. Let&amp;#39;s add some front-end code.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Developing the Front-end&lt;/h2&gt;&lt;p&gt;Create &lt;code&gt;chat.js&lt;/code&gt;, and place it within the &lt;code&gt;public&lt;/code&gt; directory of your application. Paste the following code:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;window.onload = function() {

    var messages = [];
    var socket = io.connect('http://localhost:3700');
    var field = document.getElementById(&amp;quot;field&amp;quot;);
    var sendButton = document.getElementById(&amp;quot;send&amp;quot;);
    var content = document.getElementById(&amp;quot;content&amp;quot;);

    socket.on('message', function (data) {
        if(data.message) {
            messages.push(data.message);
            var html = '';
            for(var i=0; i&amp;lt;messages.length; i++) {
                html += messages[i] + '&amp;lt;br /&amp;gt;';
            }
            content.innerHTML = html;
        } else {
            console.log(&amp;quot;There is a problem:&amp;quot;, data);
        }
    });

    sendButton.onclick = function() {
        var text = field.value;
        socket.emit('send', { message: text });
    };

}
&lt;/pre&gt;&lt;p&gt;Our logic is wrapped in a &lt;code&gt;.onload&lt;/code&gt; handler just to ensure that all the markup and external JavaScript is fully loaded. In the next few lines, we create an array, which will store all the messages, a &lt;code&gt;socket&lt;/code&gt; object, and few shortcuts to our DOM elements. Again, similar to the back-end, we bind a function, which will react to the socket&amp;#39;s activity. In our case, this is an event, named &lt;code&gt;message&lt;/code&gt;. When such an event occurs, we expect to receive an object, &lt;em&gt;data&lt;/em&gt;, with the property, &lt;code&gt;message&lt;/code&gt;. Add that message to our storage and update the &lt;code&gt;content&lt;/code&gt; &lt;code&gt;div&lt;/code&gt;. We&amp;#8217;ve also included the logic for sending the message. It&amp;#8217;s quite simple, simply emitting a message with the name, &lt;em&gt;send&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;If you open &lt;em&gt;http://localhost:3700&lt;/em&gt;, you will encounter some errors popup. That&amp;#39;s because we need to update &lt;code&gt;page.jade&lt;/code&gt; to contain the necessary JavaScript files.&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;head
    title= &amp;quot;Real time web chat&amp;quot;
    script(src='/chat.js')
    script(src='/socket.io/socket.io.js')
&lt;/pre&gt;&lt;p&gt;Notice that Socket.io manages the delivery of &lt;em&gt;socket.io.js&lt;/em&gt;. You don&amp;#39;t have to worry about manually downloading this file.&lt;/p&gt;&lt;p&gt;We can again run our server with &lt;code&gt;node index.js&lt;/code&gt; in the console and open &lt;em&gt;http://localhost:3700&lt;/em&gt;. You should see the welcome message. Of course, if you send something, it should be shown in the content&amp;#39;s &lt;code&gt;div&lt;/code&gt;. If you want to be sure that it works, open a new tab (or, better, a new browser) and load the application. The great thing about Socket.io is that it works even if you stop the NodeJS server. The front-end will continue to work. Once the server is booted up again, your chat will be fine too.&lt;/p&gt;&lt;p&gt;In its current state, our chat is not perfect, and requires some improvements.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Improvements&lt;/h2&gt;&lt;p&gt;The first change that we need to make is to the identity of the messages. Currently, it&amp;#39;s not clear which messages is sent by whom. The good thing is that we don&amp;#39;t have to update our NodeJS code to achieve this. That&amp;#39;s because the server simply forwards the &lt;code&gt;data&lt;/code&gt; object. So, we need to add a new property there, and read it later. Before making corrections to &lt;code&gt;chat.js&lt;/code&gt;, let&amp;#8217;s add a new &lt;code&gt;input&lt;/code&gt; field, where the user may add his/her name. Within &lt;code&gt;page.jade&lt;/code&gt;, change the &lt;code&gt;controls&lt;/code&gt; &lt;code&gt;div&lt;/code&gt;:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;.controls
    | Name: 
    input#name(style='width:350px;')
    br
    input#field(style='width:350px;')
    input#send(type='button', value='send')
&lt;/pre&gt;&lt;p&gt;Next, in &lt;em&gt;code.js&lt;/em&gt;:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;window.onload = function() {

    var messages = [];
    var socket = io.connect('http://localhost:3700');
    var field = document.getElementById(&amp;quot;field&amp;quot;);
    var sendButton = document.getElementById(&amp;quot;send&amp;quot;);
    var content = document.getElementById(&amp;quot;content&amp;quot;);
    var name = document.getElementById(&amp;quot;name&amp;quot;);

    socket.on('message', function (data) {
        if(data.message) {
            messages.push(data);
            var html = '';
            for(var i=0; i&amp;lt;messages.length; i++) {
                html += '&amp;lt;b&amp;gt;' + (messages[i].username ? messages[i].username : 'Server') + ': &amp;lt;/b&amp;gt;';
                html += messages[i].message + '&amp;lt;br /&amp;gt;';
            }
            content.innerHTML = html;
        } else {
            console.log(&amp;quot;There is a problem:&amp;quot;, data);
        }
    });

    sendButton.onclick = function() {
        if(name.value == &amp;quot;&amp;quot;) {
            alert(&amp;quot;Please type your name!&amp;quot;);
        } else {
            var text = field.value;
            socket.emit('send', { message: text, username: name.value });
        }
    };

}
&lt;/pre&gt;&lt;p&gt;To summarize the changes, we&amp;#8217;ve:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Added a new shortcut for the username&amp;#39;s &lt;code&gt;input&lt;/code&gt; field&lt;/li&gt;&lt;li&gt;Updated the presentation of the messages a bit&lt;/li&gt;&lt;li&gt;Appended a new &lt;code&gt;username&lt;/code&gt; property to the object, which is sent to the server&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If the the number of messages becomes too high, the user will need to scroll the &lt;code&gt;div&lt;/code&gt;:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;content.innerHTML = html;
content.scrollTop = content.scrollHeight;
&lt;/pre&gt;&lt;p&gt;Keep in mind that the above solution will likely not work in IE7 and below, but that&amp;#8217;s okay: it&amp;#8217;s time for IE7 to fade away. However, if you want to ensure support, feel free to use jQuery:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;$(&amp;quot;#content&amp;quot;).scrollTop($(&amp;quot;#content&amp;quot;)[0].scrollHeight);
&lt;/pre&gt;&lt;p&gt;It would also be nice if the input field is cleared after sending the message:&lt;/p&gt;&lt;pre class="brush: plain; title: ; notranslate"&gt;socket.emit('send', { message: text, username: name.value });
field.value = &amp;quot;&amp;quot;;
&lt;/pre&gt;&lt;p&gt;The final boring problem is the clicking of the &lt;em&gt;send&lt;/em&gt; button each time. With a touch of jQuery, we can listen for when the user presses the &lt;code&gt;Enter&lt;/code&gt; key.&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;$(document).ready(function() {
    $(&amp;quot;#field&amp;quot;).keyup(function(e) {
        if(e.keyCode == 13) {
            sendMessage();
        }
    });
});
&lt;/pre&gt;&lt;p&gt;The function, &lt;code&gt;sendMessage&lt;/code&gt;, could be registered, like so:&lt;/p&gt;&lt;pre class="brush: jscript; title: ; notranslate"&gt;sendButton.onclick = sendMessage = function() {
    ...
};
&lt;/pre&gt;&lt;p&gt;Please note that this isn&amp;#8217;t a best practice, as it is registered as a global function. But, for our little test here, it&amp;#8217;ll be fine.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;NodeJS is an extremely useful technology, and provides us with a great deal of power and joy, especially when considering the fact that we can write pure JavaScript. As you can see, with only a few lines of code, we managed to write a fully functional real time chat application. Pretty neat!&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt; Want to learn more about building web apps with ExpressJS? &lt;a
href="https://tutsplus.com/course/building-web-apps-in-node-and-express/"&gt;We&amp;#8217;ve got you covered!&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=eOVTqZbxzsA:iPYAPfL2ZpQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=eOVTqZbxzsA:iPYAPfL2ZpQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=eOVTqZbxzsA:iPYAPfL2ZpQ:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=eOVTqZbxzsA:iPYAPfL2ZpQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=eOVTqZbxzsA:iPYAPfL2ZpQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=eOVTqZbxzsA:iPYAPfL2ZpQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=eOVTqZbxzsA:iPYAPfL2ZpQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=eOVTqZbxzsA:iPYAPfL2ZpQ:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/eOVTqZbxzsA" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/real-time-chat-with-nodejs-socket-io-and-expressjs/feed/</wfw:commentRss> <slash:comments>27</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/javascript-ajax/real-time-chat-with-nodejs-socket-io-and-expressjs/</feedburner:origLink></item> <item><title>Mass Assignment, Rails, and You</title><link>http://feedproxy.google.com/~r/nettuts/~3/XpoNYQDjTzU/</link> <comments>http://net.tutsplus.com/tutorials/ruby/mass-assignment-rails-and-you/#comments</comments> <pubDate>Mon, 13 May 2013 18:00:20 +0000</pubDate> <dc:creator>Arun Srinivasan</dc:creator> <category><![CDATA[Ruby]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[tips]]></category> <guid isPermaLink="false">http://net.tutsplus.com/?p=31695</guid> <description>&lt;a
href='http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31695&amp;c=1660132084' target='_blank'&gt;&lt;img
src='http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31695&amp;c=1660132084' border='0' alt='' /&gt;&lt;/a&gt;&lt;p&gt;Early in 2012, a developer, named Egor Homakov, took advantage of a security hole at &lt;a
href="github"&gt;Github&lt;/a&gt; (a Rails app) to gain commit access to the &lt;a
href="https://github.com/rails/rails"&gt;Rails&lt;/a&gt; project.&lt;/p&gt;&lt;p&gt;His intent was mostly to point out a common security issue with many Rails apps that results from a feature, known as mass assignment (and did so rather loudly). In this article, we&amp;#39;ll review what mass assignment is, how it can be a problem, and what you can do about it in your own applications.&lt;/p&gt;&lt;p&gt;&lt;span
id="more-31695"&gt;&lt;/span&gt;&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;What is Mass Assignment?&lt;/h2&gt;&lt;p&gt;To begin, let&amp;#39;s first take a look at what mass assignment means, and why it exists. By way of an example, imagine that we have the following &lt;code&gt;User&lt;/code&gt; class in our application:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;# Assume the following fields: [:id, :first, :last, :email]
class User &amp;lt; ActiveRecord::Base
end
&lt;/pre&gt;&lt;p&gt;Mass assignment allows us to set a bunch of attributes at once:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;attrs = {:first =&amp;gt; &amp;quot;John&amp;quot;, :last =&amp;gt; &amp;quot;Doe&amp;quot;, :email =&amp;gt; &amp;quot;john.doe@example.com&amp;quot;}
user = User.new(attrs)
user.first #=&amp;gt; &amp;quot;John&amp;quot;
user.last  #=&amp;gt; &amp;quot;Doe&amp;quot;
user.email #=&amp;gt; &amp;quot;john.doe@example.com&amp;quot;
&lt;/pre&gt;&lt;p&gt;Without the convenience of mass assignment, we&amp;#39;d have to write an assignment statement for each attribute to achieve the same result. Here&amp;#8217;s an example:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;attrs = {:first =&amp;gt; &amp;quot;John&amp;quot;, :last =&amp;gt; &amp;quot;Doe&amp;quot;, :email =&amp;gt; &amp;quot;john.doe@example.com&amp;quot;}
user = User.new
user.first = attrs[:first]
user.last  = attrs[:last]
user.email = attrs[:email]
user.first #=&amp;gt; &amp;quot;John&amp;quot;
user.last  #=&amp;gt; &amp;quot;Doe&amp;quot;
user.email #=&amp;gt; &amp;quot;john.doe@example.com&amp;quot;
&lt;/pre&gt;&lt;p&gt;Obviously, this can get tedious and painful; so we bow at the feet of laziness and say, yes yes, mass assignment is a good thing.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;The (Potential) Problem With Mass Assignment&lt;/h2&gt;&lt;blockquote
class="pullquote"&gt;&lt;p&gt; One problem with sharp tools is that you can cut yourself with them.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;But wait! One problem with sharp tools is that you can cut yourself with them. Mass assignment is no exception to this rule.&lt;/p&gt;&lt;p&gt;Suppose now that our little imaginary application has acquired the ability to fire missiles. As we don&amp;#39;t want the world to turn to ash, we add a boolean permission field to the &lt;code&gt;User&lt;/code&gt; model to decide who can fire missiles.&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;class AddCanFireMissilesFlagToUsers &amp;lt; ActiveRecord::Migration
  def change
    add_column :users, :can_fire_missiles, :boolean, :default =&amp;gt; false
  end
end
&lt;/pre&gt;&lt;p&gt;Let&amp;#39;s also assume that we have a way for users to edit their contact information: this might be a form somewhere that is accessible to the user with text fields for the user&amp;#39;s first name, last name, and email address.&lt;/p&gt;&lt;p&gt;Our friend John Doe decides to change his name and update his email account. When he submits the form, the browser will issue a request similar to the following:&lt;/p&gt;&lt;pre class="brush: plain; title: ; notranslate"&gt;PUT http://missileapp.com/users/42?user[first]=NewJohn&amp;amp;user[email]=john.doe@newemail.com
&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;update&lt;/code&gt; action within the &lt;code&gt;UsersController&lt;/code&gt; might look something like:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;def update
  user = User.find(params[:id])
  if user.update_attributes(params[:user]) # Mass assignment!
    redirect_to home_path
  else
    render :edit
  end
end
&lt;/pre&gt;&lt;p&gt;Given our example request, the &lt;code&gt;params&lt;/code&gt; hash will look similar to:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;{:id =&amp;gt; 42, :user =&amp;gt; {:first =&amp;gt; &amp;quot;NewJohn&amp;quot;, :email =&amp;gt; &amp;quot;john.doe@newemail.com&amp;quot;}
# :id - parsed by the router
# :user - parsed from the incoming querystring
&lt;/pre&gt;&lt;p&gt;Now let&amp;#39;s say that NewJohn gets a little sneaky. You don&amp;#39;t necessarily need a browser to issue an HTTP request, so he writes a script that issues the following request:&lt;/p&gt;&lt;pre class="brush: plain; title: ; notranslate"&gt;PUT http://missileapp.com/users/42?user[can_fire_missiles]=true
&lt;/pre&gt;&lt;blockquote
class="pullquote"&gt;&lt;p&gt; Fields, like &lt;code&gt;:admin&lt;/code&gt;, &lt;code&gt;:owner&lt;/code&gt;, and &lt;code&gt;:public_key&lt;/code&gt;, are quite easily guessable.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;When this request hits our &lt;code&gt;update&lt;/code&gt; action, the &lt;code&gt;update_attributes&lt;/code&gt; call will see &lt;code&gt;{:can_fire_missiles =&gt; true}&lt;/code&gt;, and give NewJohn the ability to fire missiles! Woe has become us.&lt;/p&gt;&lt;p&gt;This is exactly how Egor Homakov gave himself commit access to the Rails project. Because Rails is so convention-heavy, fields like &lt;code&gt;:admin&lt;/code&gt;, &lt;code&gt;:owner&lt;/code&gt;, and &lt;code&gt;:public_key&lt;/code&gt; are quite easily guessable. Further, if there aren&amp;#39;t protections in place, you can gain access to things that you&amp;#39;re not supposed to be able to touch.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;How to Deal With Mass Assignment&lt;/h2&gt;&lt;p&gt;So how do we protect ourselves from wanton mass assignment? How do we prevent the NewJohns of the world from firing our missiles with reckless abandon?&lt;/p&gt;&lt;p&gt;Luckily, Rails provides a couple tools to manage the issue: &lt;code&gt;attr_protected&lt;/code&gt; and &lt;code&gt;attr_accessible&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;&lt;code&gt;attr_protected&lt;/code&gt;: The BlackList&lt;/h3&gt;&lt;p&gt;Using &lt;code&gt;attr_protected&lt;/code&gt;, you can specify which fields may never be &lt;em&gt;mass-ly&lt;/em&gt; assignable:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;class User &amp;lt; ActiveRecord::Base
  attr_protected :can_fire_missiles
end
&lt;/pre&gt;&lt;p&gt;Now, any attempt to mass-assign the &lt;code&gt;can_fire_missiles&lt;/code&gt; attribute will fail.&lt;/p&gt;&lt;h3&gt;&lt;code&gt;attr_accessible&lt;/code&gt;: The WhiteList&lt;/h3&gt;&lt;p&gt;The problem with &lt;code&gt;attr_protected&lt;/code&gt; is that it&amp;#39;s too easy to forget to add a newly implemented field to the list.&lt;/p&gt;&lt;p&gt;This is where &lt;code&gt;attr_accessible&lt;/code&gt; comes in. As you might have guessed, it&amp;#39;s the opposite of &lt;code&gt;attr_protected&lt;/code&gt;: only list the attributes that you want to be mass-assignable.&lt;/p&gt;&lt;p&gt;As such, we can switch our &lt;code&gt;User&lt;/code&gt; class to this approach:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;class User &amp;lt; ActiveRecord::Base
  attr_accessible :first, :last, :email
end
&lt;/pre&gt;&lt;p&gt;Here, we&amp;#39;re explicitly listing out what can be mass-assigned. Everything else will be disallowed. The advantage here is that if we, say, add an &lt;code&gt;admin&lt;/code&gt; flag to the &lt;code&gt;User&lt;/codE&gt; model, it will automatically be safe from mass-assignment.&lt;/p&gt;&lt;p&gt;As a general rule, you should prefer &lt;code&gt;attr_accessible&lt;/code&gt; to &lt;code&gt;attr_protected&lt;/code&gt;, as it helps you err on the side of caution.&lt;/p&gt;&lt;h3&gt;Mass Assignment Roles&lt;/h3&gt;&lt;p&gt;Rails 3.1 introduced the concept of mass-assignment &amp;quot;roles&amp;quot;. The idea is that you can specify different &lt;code&gt;attr_protected&lt;/code&gt; and &lt;code&gt;attr_accessible&lt;/code&gt; lists for different situations.&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;class User &amp;lt; ActiveRecord::Base
  attr_accessible :first, :last, :email             # :default role
  attr_accessible :can_fire_missiles, :as =&amp;gt; :admin # :admin role
end

user = User.new({:can_fire_missiles =&amp;gt; true}) # uses the :default role  
user.can_fire_missiles #=&amp;gt; false  

user2 = User.new({:can_fire_missiles =&amp;gt; true}, :as =&amp;gt; :admin)  
user.can_fire_missiles #=&amp;gt; true  
&lt;/pre&gt;&lt;h3&gt;Application-wide Configuration&lt;/h3&gt;&lt;p&gt;You can control mass assignment behavior in your application by editing the &lt;code&gt;config.active_record.whitelist_attributes&lt;/code&gt; setting within the &lt;code&gt;config/application.rb&lt;/code&gt; file.&lt;/p&gt;&lt;p&gt;If set to &lt;code&gt;false&lt;/code&gt;, mass assignment protection will only be activated for the models where you specify an &lt;code&gt;attr_protected&lt;/code&gt; or &lt;code&gt;attr_accessible&lt;/code&gt; list.&lt;/p&gt;&lt;p&gt;If set to &lt;code&gt;true&lt;/code&gt;, mass assignment will be impossible for all models unless they specify an &lt;code&gt;attr_protected&lt;/code&gt; or &lt;code&gt;attr_accessible&lt;/code&gt; list. Please note that this option is enabled by default from Rails 3.2.3 forward.&lt;/p&gt;&lt;h3&gt;Strictness&lt;/h3&gt;&lt;p&gt;Beginning with Rails 3.2, there is additionally a configuration option to control the strictness of mass assignment protection: &lt;code&gt;config.active_record.mass_assignment_sanitizer&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;If set to &lt;code&gt;:strict&lt;/code&gt;, it will raise an &lt;code&gt;ActiveModel::MassAssignmentSecurity::Error&lt;/code&gt; any time that your application attempts to mass-assign something it shouldn&amp;#39;t. You&amp;#39;ll need to handle these errors explicitly. As of v3.2, this option is set for you in the development and test environments (but not production), presumably to help you track down where mass-assignment issues might be.&lt;/p&gt;&lt;p&gt;If not set, it will handle mass-assignment protection silently - meaning that it will only set the attributes it&amp;#39;s supposed to, but won't raise an error.&lt;/p&gt;&lt;hr
/&gt;&lt;h2&gt;Rails 4 Strong Parameters: A Different Approach&lt;/h2&gt;&lt;blockquote
class="pullquote"&gt;&lt;p&gt; Mass assignment security is really about handling untrusted input.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;The Homakov Incident initiated a conversation around mass assignment protection in the Rails community (and onward to other languages, as well); an interesting question was raised: does mass assignment security belong in the model layer?&lt;/p&gt;&lt;p&gt;Some applications have complex authorization requirements. Trying to handle all special cases in the model layer can begin to feel clunky and over-complicated, especially if you find yourself plastering &lt;code&gt;roles&lt;/code&gt; all over the place.&lt;/p&gt;&lt;p&gt;A key insight here is that mass assignment security is really about handling untrusted input. As a Rails application receives user input in the controller layer, developers began wondering whether it might be better to deal with the issue there instead of ActiveRecord models.&lt;/p&gt;&lt;p&gt;The result of this discussion is the &lt;a
href="strongparameters"&gt;Strong Parameters&lt;/a&gt; gem, available for use with Rails 3, and a default in the upcoming Rails 4 release.&lt;/p&gt;&lt;p&gt;Assuming that our missile application is bult on Rails 3, here&amp;#39;s how we might update it for use with the stong parameters gem:&lt;/p&gt;&lt;h4&gt;Add the gem&lt;/h4&gt;&lt;p&gt;Add the following line to the Gemfile:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;gem strong_parameters
&lt;/pre&gt;&lt;h4&gt;Turn off model-based mass assignment protection&lt;/h4&gt;&lt;p&gt;Within &lt;code&gt;config/application.rb&lt;/code&gt;:&lt;/p&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;config.active_record.whitelist_attributes = false
&lt;/pre&gt;&lt;h4&gt;Tell the models about it&lt;/h4&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;class User &amp;lt; ActiveRecord::Base
  include ActiveModel::ForbiddenAttributesProtection
end
&lt;/pre&gt;&lt;h4&gt;Update the controllers&lt;/h4&gt;&lt;pre class="brush: ruby; title: ; notranslate"&gt;class UsersController &amp;lt; ApplicationController
  def update
    user = User.find(params[:id])
    if user.update_attributes(user_params) # see below
      redirect_to home_path
    else
      render :edit
    end
  end

  private

  # Require that :user be a key in the params Hash,
  # and only accept :first, :last, and :email attributes
  def user_params
    params.require(:user).permit(:first, :last, :email)
  end
end
&lt;/pre&gt;&lt;p&gt;Now, if you attempt something like &lt;code&gt;user.update_attributes(params)&lt;/code&gt;, you&amp;#39;ll get an error in your application. You must first call &lt;code&gt;permit&lt;/code&gt; on the &lt;code&gt;params&lt;/code&gt; hash with the keys that are allowed for a specific action.&lt;/p&gt;&lt;p&gt;The advantage to this approach is that you must be explicit about which input you accept at the point that you&amp;#39;re dealing with the input.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If this was a Rails 4 app, the controller code is all we&amp;#39;d need; the strong parameters functionality will be baked in by default. As a result, you won&amp;#39;t need the include in the model or the separate gem in the Gemfile.&lt;/p&gt;&lt;/blockquote&gt;&lt;hr
/&gt;&lt;h2&gt;Wrapping Up&lt;/h2&gt;&lt;p&gt;Mass assignment can be an incredibly useful feature when writing Rails code. In fact, it&amp;#39;s nearly impossible to write reasonable Rails code without it. Unfortunately, mindless mass assignment is also fraught with peril.&lt;/p&gt;&lt;p&gt;Hopefully, you&amp;#39;re now equipped with the necessary tools to navigate safely in the mass assignment waters. Here&amp;#39;s to fewer missiles!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=XpoNYQDjTzU:zFQKX_mHCTo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=XpoNYQDjTzU:zFQKX_mHCTo:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=XpoNYQDjTzU:zFQKX_mHCTo:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=XpoNYQDjTzU:zFQKX_mHCTo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=XpoNYQDjTzU:zFQKX_mHCTo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=XpoNYQDjTzU:zFQKX_mHCTo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?i=XpoNYQDjTzU:zFQKX_mHCTo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/nettuts?a=XpoNYQDjTzU:zFQKX_mHCTo:TzevzKxY174"&gt;&lt;img src="http://feeds.feedburner.com/~ff/nettuts?d=TzevzKxY174" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/nettuts/~4/XpoNYQDjTzU" height="1" width="1"/&gt;</description> <wfw:commentRss>http://net.tutsplus.com/tutorials/ruby/mass-assignment-rails-and-you/feed/</wfw:commentRss> <slash:comments>5</slash:comments> <feedburner:origLink>http://net.tutsplus.com/tutorials/ruby/mass-assignment-rails-and-you/</feedburner:origLink></item> </channel> </rss><!-- Dynamic Page Served (once) in 1.010 seconds -->
