<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
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/"
><channel><title>Nettuts+</title> <atom:link href="http://net.tutsplus.com/feed/" rel="self" type="application/rss+xml" /><link>http://net.tutsplus.com</link> <description>Web Development &#38; Design Tutorials</description> <lastBuildDate>Tue, 09 Feb 2010 21:25:53 +0000</lastBuildDate> <generator>http://wordpress.org/?v=2.9.1</generator> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <item><title>Quick Tip: How to Work with @Font-face</title><link>http://net.tutsplus.com/videos/screencasts/quick-tip-how-to-work-with-font-face/</link> <comments>http://net.tutsplus.com/videos/screencasts/quick-tip-how-to-work-with-font-face/#comments</comments> <pubDate>Tue, 09 Feb 2010 20:24:44 +0000</pubDate> <dc:creator>Jeffrey Way</dc:creator> <category><![CDATA[Screencasts]]></category> <category><![CDATA[CSS]]></category> <category><![CDATA[css3]]></category> <category><![CDATA[font replacement]]></category> <category><![CDATA[font-face]]></category> <category><![CDATA[fontface]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9219</guid> <description><![CDATA[<img
src="http://nettuts.s3.cdn.plus.org/569_fontface/200x200.png" alt="Quick Tip: How to Work with @Font-face" />]]></description> <content:encoded><![CDATA[<p> Due to the fact that @font-face can be a bit overly complicated, it hasn&#8217;t caught on quite as much as it should. Once you start reading about licensing, different font formats, browser consistencies, it can potentially become more trouble than it&#8217;s worth.</p><p>But &#8211; in five minutes, I&#8217;ll try to simplify the process of working with custom fonts as much as I possibly can. Services like <a
href="http://www.fontsquirrel.com/">Font Squirrel</a> help to make the task a cinch!</p><p><span
id="more-9219"></span></p><div
class="tutorial_image"> <a
href="http://nettuts.s3.amazonaws.com/569_fontface/fontface.zip"><img
src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg"></a><br
/> <a
href="http://nettuts.s3.amazonaws.com/569_fontface/fontface/index.html"><img
src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg"></a></div><div
class="tutorial_image"> <object
classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='600' height='369'><param
name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param
name='flashvars' value='i=45747' /><param
name='allowFullScreen' value='true' /><embed
src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=45747' allowFullScreen='true' width='600' height='369' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></div><h3>Final CSS</h3><pre name="code" class="css">
@font-face {
font-family: 'blok-regular';
src: url('type/Blokletters-Potlood.eot');
src: local('Blokletters Potlood Potlood'),
 local('Blokletters-Potlood'),
 url('type/Blokletters-Potlood.ttf') format('truetype');
}

@font-face {
font-family: 'blok-italic';
src: url('type/Blokletters-Balpen.eot');
src: local('Blokletters Balpen Balpen'),
 local('Blokletters-Balpen'),
 url('type/Blokletters-Balpen.ttf') format('truetype');
}

@font-face {
font-family: 'blok-heavy';
src: url('type/Blokletters-Viltstift.eot');
src: local('Blokletters Viltstift Viltstift'),
 local('Blokletters-Viltstift'),
 url('type/Blokletters-Viltstift.ttf') format('truetype');
}

h1 { font-family: blok-heavy, helvetica, arial; }
</pre><p> Notice how we&#8217;re referencing both an .eot and .ttf font? This is because, of course, Internet Explorer only uses its own format, that has yet to truly catch on. As such, we must first import that .eot file, and then move on to the different formats for Firefox, Safari, etc. <strong>It&#8217;s essential that you load the .eot version first. </strong></p><p>Next, we search for the font on the user&#8217;s computer by using the &#8220;local&#8221; attribute. If it&#8217;s unfound, only then do we pass a url that will load the font.</p><h3>Why Doesn&#8217;t IE Try to Load the TTF Fonts?</h3><p> This was definitely a concern. If Explorer can&#8217;t work with the truetype format, we don&#8217;t want to waste time trying to download the font. Luckily, because of all those local attributes, and the commas, IE won&#8217;t understand any of it. As such, it will simply skip the line all together, thus, only utilizing the .eot version.</p><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/videos/screencasts/quick-tip-how-to-work-with-font-face/feed/</wfw:commentRss> <slash:comments>36</slash:comments> </item> <item><title>How to Build an Unobtrusive Login System in Rails</title><link>http://net.tutsplus.com/tutorials/ruby/how-to-build-an-unobtrusive-login-system-in-rails/</link> <comments>http://net.tutsplus.com/tutorials/ruby/how-to-build-an-unobtrusive-login-system-in-rails/#comments</comments> <pubDate>Tue, 09 Feb 2010 19:09:13 +0000</pubDate> <dc:creator>Adam Hawkins</dc:creator> <category><![CDATA[Ruby]]></category> <category><![CDATA[login]]></category> <category><![CDATA[rails]]></category> <category><![CDATA[ruby on rails]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9194</guid> <description><![CDATA[<img
src="http://nettuts.s3.amazonaws.com/568_login/jquery/200x200.png" alt="How to Build an Unobtrusive Login System in Rails" />]]></description> <content:encoded><![CDATA[<p>An unobtrusive login system is one that gets out of the user&#8217;s way. It will make your application nicer and more polished. This article will guide you through the process of setting up user logins, then ajaxifying the process by moving the form into a modal box that communicates with the server. Additionally, this article will show you how to create the setup using jQuery and Prototype so you can choose your favorite library. This article assumes that you have experience with Rails and jQuery or Prototype.</p><p><span
id="more-9194"></span></p><div
class="tutorial_image"> <a
href="http://github.com/Adman65/Unobtrusive-Login/"><img
src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_src_nm.jpg"></a><br
/> <a
href="http://nettuts-unobtrusive-login.heroku.com/"><img
src="http://net.tutsplus.com/wp-content/themes/nettuts/site_images/button_demo_nm.jpg"></a></div><p>You can use Adman65/nettuts for a successful login. Be sure to use bad credentials so you can see how everything works.</p><h3>What We&#8217;re Making</h3><div
class="tutorial_image"> <a
href="http://nettuts-unobtrusive-login.heroku.com/"><br
/> <img
src="http://nettuts.s3.cdn.plus.org/568_login/login4.png" alt="Final Project" /><br
/> </a></div><h3 id="gettingstarted">Getting Started</h3><p>We&#8217;re going to start by creating a dummy application that has a public and private page. The root url is the public page. There&#8217;s a login link on the public page. If the user logs in successfully, they&#8217;re redirected to the private page. If not, they&#8217;re redirected back to the login form. The private page shows the user name. We&#8217;ll use this as the starting point for ajaxifying the site.</p><p>The first step is using the rails command to generate a new application, then install and setup up authlogic.</p><pre name="code" class="ruby">$ cd into-a-directory
$ rails unobtrusive-login
</pre><p>Add authlogic.</p><pre name="code" class="ruby"># /config/environment.rb
config.gem 'authlogic'
</pre><p>Now install the gems.</p><pre name="code" class="ruby">$ sudo gem install gemcutter
$ sudo gem tumble
$ sudo rake gems:install
</pre><p>Next create a user model and add the required authlogic columns to the migration.</p><pre name="code" class="ruby">$ ./script/generate model User
exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/user.rb
create  test/unit/user_test.rb
create  test/fixtures/users.yml
create  db/migrate
create  db/migrate/20100102082657_create_users.rb
</pre><p>Now, add the columns to the new migration.</p><pre name="code" class="ruby">class CreateUsers &lt; ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string    :login,               :null =&gt; false
      t.string    :crypted_password,    :null =&gt; false
      t.string    :password_salt,       :null =&gt; false
      t.string    :persistence_token,   :null =&gt; false
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end
</pre><p>Migrate the database.</p><pre name="code" class="ruby">$ rake db:migrate
</pre><p>Include authlogic in the user model.</p><pre name="code" class="ruby"># /app/models/user.rb
class User &lt; ActiveRecord::Base
  acts_as_authentic
end
</pre><p>Now we can create a user. Since this is a demo app, web based functionality for signing up isn&#8217;t required. So open up the console and create a user:</p><pre name="code" class="ruby">$ ./script/console
&gt;&gt; me = User.create(:login =&gt; 'Adman65', :password =&gt; 'nettuts', :password_confirmation =&gt; 'nettuts')
</pre><p>Now we have a user in the system, but we have no way to login or logout. We need to create the models, controllers, and views for this. Authlogic has its own class for tracking logins. We can use the generator for that:</p><pre name="code" class="ruby"># create the user session
$ ./script/generate UserSession
</pre><p>Next we need to generate the controller that will login/logout users. You can create sessions just like any other resource in Rails.</p><pre name="code" class="ruby"># create the session controller
$ ./script/generate controller UserSessions
</pre><p>Now set its contents to:</p><pre name="code" class="ruby"># /app/controllers/user_sessions_controller.rb
class UserSessionsController &lt; ApplicationController
  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])
    if @user_session.save
      flash[:notice] = "Login successful!"
      redirect_back_or_default user_path
    else
      render :action =&gt; :new
    end
  end
end
</pre><p>It looks exactly the same as a controller that was generated via scaffolding. Now create the users controller which has public and private content. Generate a users controller. Inside the controller we&#8217;ll use a before filter to limit access to the private areas. The index action is public and show is private.</p><pre name="code" class="ruby"># create the users controller
$ ./script/generate controller users
</pre><p>Update its contents:</p><pre name="code" class="ruby"># /app/controllers/users_controller.rb
class UsersController &lt; ApplicationController
  before_filter :login_required, <img src='http://net.tutsplus.cdn.plus.org/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly =&gt; :show

  def index
  end

  def show
    @user = current_user
  end

  private
  def login_required
    unless current_user
      flash[:error] = 'You must be logged in to view this page.'
      redirect_to new_user_session_path
    end
  end
end
</pre><p>You should notice that current_user is an undefined method at this point. Define these methods in ApplicationController. Open up application_controller.rb and update its contents:</p><pre name="code" class="ruby"># application controller
class ApplicationController &lt; ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details

  # From authlogic
  filter_parameter_logging :password, :password_confirmation
  helper_method :current_user_session, :current_user

  private
  def current_user_session
    @current_user_session ||= UserSession.find
  end

  def current_user
    @current_user ||= current_user_session &amp;&amp; current_user_session.user
  end
end
</pre><p>At this point the models and controllers are complete, but views aren&#8217;t. We need to create views for a login form and the public and private content. We&#8217;ll use the nifty-generators gem to create a basic layout.</p><pre name="code" class="ruby">$ sudo gem install nifty-generators
$ ./script/generate nifty_layout
</pre><p>Time to create the login form. We&#8217;re going to use a partial for this because in the future we&#8217;ll use the partial to render just the login form in the modal box. Here&#8217;s the code to create the login form. It&#8217;s exactly the same as if you were creating a blog post or any other model.</p><pre name="code" class="ruby"># create the login views
# /app/views/user_sessions/_form.html.erb
&lt;% form_for(@user_session, :url =&gt; user_session_path) do |form| %&gt;
  &lt;%= form.error_messages %&gt;

  &lt;p&gt;
    &lt;%= form.label :login %&gt;
    &lt;%= form.text_field :login %&gt;
  &lt;/p&gt;

  &lt;p&gt;
    &lt;%= form.label :password %&gt;
    &lt;%= form.password_field :password %&gt;
  &lt;/p&gt;

  &lt;%= form.submit 'Login' %&gt;
&lt;% end %&gt;
</pre><p>Render the partial in the new view:</p><pre name="code" class="ruby"># /app/views/user_sessions/new.html.erb
&lt;% title 'Login Please' %&gt;
&lt;%= render :partial =&gt; 'form' %&gt;
</pre><p>Create some basic pages for the public and private content. The index action shows public content and show displays private content.</p><pre name="code" class="ruby"># create the dummy public page
# /app/views/users/index.html.erb
&lt;% title 'Unobtrusive Login' %&gt;

&lt;p&gt;Public Facing Content&lt;/p&gt;

&lt;%= link_to 'Login', new_user_session_path %&gt;
</pre><p>And for the private page:</p><pre name="code" class="ruby"># create the dummy private page
# /app/views/users/show.html.erb
&lt;% title 'Welcome' %&gt;
&lt;h2&gt;Hello &lt;%=h @user.login %&gt;&lt;/h2&gt;

&lt;%= link_to 'Logout', user_session_path, :method =&gt; :delete %&gt;
</pre><p>Delete the file /public/index.html and start the server. You can now log in and logout of the application.</p><pre name="code" class="ruby">$ ./script/server
</pre><p>Here are some screenshots of the demo application. The first one is the public page.</p><div
class="tutorial_image"><img
id="publicpage" src="http://nettuts.s3.cdn.plus.org/568_login/login1.png" alt="Public Page" title="" /></div><p>Now the login form</p><div
class="tutorial_image"><img
id="loginpage" src="http://nettuts.s3.cdn.plus.org/568_login/login2.png" alt="Login Page" title="" /></div><p>And the private page</p><div
class="tutorial_image"><img
id="privatepage" src="http://nettuts.s3.cdn.plus.org/568_login/login3.png" alt="Private Page" title="" /></div><p>And finally, access denied when you try to visit http://localhost:3000/user</p><div
class="tutorial_image"><img
id="accessdenied" src="http://nettuts.s3.cdn.plus.org/568_login/login4.png" alt="Access Denied" title="" /></div><h3 id="theajaxloginprocess">The AJAX Login Process</h3><p>Before continuing, we need to understand how the server and browser are going to work together to complete this process. We know that we&#8217;ll need to use some JavaScript for the modal box and the server to validate logins. Let&#8217;s be clear on how this is going to work. The user clicks the login link, then a modal box appears with the login form. The user fills in the form and is either redirected to the private page, or the modal box is refreshed with a new login form. The next question is how do you refresh the modal box or tell the browser what to do after the user submits the form? Rails has respond_to blocks. With respond_to, you can tell the controller to render different content if the user requested XML, HTML, JavaScript, YAML etc. So when the user submits the form, the server can return some JavaScript to execute in the browser. We&#8217;ll use this render a new form or a redirect. Before diving any deeper, let&#8217;s go over the process in order.</p><ol><li>User goes to the public page</li><li>User clicks the login link</li><li>Modal box appears</li><li>User fills in the form</li><li>Form is submitted to the server</li><li>Server returns JavaScript for execution</li><li>Browser executes the JavaScript which either redirects or updates the modal box.</li></ol><p>That&#8217;s the high level. Here&#8217;s the low level implementation.</p><ol><li>User visits the public page</li><li>The public page has some JavaScript that runs when the DOM is ready that attaches JavaScript to the login link. That javscript does an XMLHTTPRequest (XHR from now on) to the server for some JavaScript. The JavaScript sets the modal box&#8217;s content to the form HTML. The JavaScript also does something very important. It binds the form&#8217;s submit action to an XHR with POST data to the form&#8217;s action. This allows the user to keep filling the login form in inside the modal box.</li><li>Modal box now has the form and required JavaScript</li><li>User clicks &#8216;Login&#8217;</li><li>The submit() function is called which does a POST XHR to the form&#8217;s action with its data.</li><li>Server either generates the JavaScript for the form or the redirect</li><li>Browser receives the JavaScript and executes it. The browser will either update the modal box, or redirect the user through window.location.</li></ol><h2 id="takingapeakattheajaxreadycontroller">Taking a Peak at the AJAX Ready Controller</h2><p>Let&#8217;s take a look at the new structure for the UserSessions controller.</p><pre name="code" class="ruby">class UserSessionsController &lt; ApplicationController
  layout :choose_layout

  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])

    if @user_session.save
      respond_to do |wants|
        wants.html { redirect_to user_path(@user_session.user) }
        wants.js { render :action =&gt; :redirect } # JavaScript to do the redirect
      end
    else
      respond_to do |wants|
        wants.html { render :new }
        wants.js # defaults to create.js.erb
      end
    end
  end

  private
  def choose_layout
    (request.xhr?) ? nil : 'application'
  end
end
</pre><p>As you can see the structure is different. Inside the if save, else conditional, respond_to is used to render the correct content. want.xx where xx is a content type. By default Prototype and jQuery request text/JavaScript. This corresponds to wants.js. We&#8217;re about ready to get started on the AJAX part. We won&#8217;t use any plugins except ones for modal boxes. We&#8217;ll use Facebox for jQuery and ModalBox for Prototype.</p><h3 id="prototype">Prototype</h3><p>Rails has built in support for Prototype. The Rail&#8217;s JavaScript helpers are Ruby functions that generate JavaScript that use Prototype. This technique is known as RJS (Ruby JavaScript). One example is remote_form_for which works like the standard for_for adds some JS bound to onsubmit that submits to the form to its action using its method with its data. I won&#8217;t use RJS in this article since I want to demonstrate vanilla JS. I think by using pure JS and eliminating the JS helpers the article will be more approachable by less experienced developers. That being said, you could easily accomplish these steps using RJS/Prototype helpers if you choose.</p><p>Adding Prototype to the application is very easy. When you use the rails command, it creates the Prototype and scriptaculous files in /public/JavaScripts. Including them is easy. Open up /app/views/layouts/application.erb and add this line inside the head tag:</p><pre name="code" class="ruby">&lt;%= JavaScript_include_tag :defaults %&gt;
</pre><p>JavaScript_include_tag creates script tags for default files in /public/JavaScripts, most importantly prototype.js, effects.js, and application.js. effects.js is scriptaculous. application.js is a file you can use to keep application specific JS. Now we need a modal box plugin. We&#8217;re going to use <a
href="http://okonet.ru/projects/modalbox/">this</a>. Its a very nice modal box plugin inspired by OSX. The source is hosted on GitHub, so you&#8217;ll have to clone and move the files in your project directory. For example:</p><pre name="code" class="html">$ cd code
$ git clone git://github.com/okonet/modalbox.git
$ cd modalbox
# move the files in the correct directories.
# move modalbox.css into /public/stylesheets
# move modalbox.js into /public/JavaScripts
# move spinner.gif into /public/images
</pre><p>Now include the stylesheets and JavaScript in your application.</p><pre name="code" class="ruby">
  &lt;%= stylesheet_link_tag &#8216;application&#8217; %>
  &lt;%= stylesheet_link_tag &#8216;modalbox&#8217; %>
  &lt;%= JavaScript_include_tag :defaults %>
  &lt;%= JavaScript_include_tag &#8216;modalbox&#8217;%></pre><p>Now let&#8217;s get our login link to open a modalbox. In order to do this we need to add some JavaScript that runs when the DOM is ready that attaches the modalbox to our link. When the user clicks the login link, the browser will do a GET to /user_sessions/new which contains the login form. The login link uses the #login-link selector. Update the login link to use the new id in /app/views/users/index.html.erb. Modify the link_to function like this:</p><pre name="code" class="ruby">&lt;%= link_to 'Login', new_user_session_path, :id =&gt; 'login-link' %&gt;
</pre><p>That gives us a#login-link. Now for the JavaScript to attach a modalbox. Add this JS in /public/JavaScripts/application.js</p><pre name="code" class="js">document.observe('dom:loaded', function() {
    $('login-link').observe('click', function(event) {
        event.stop();
        Modalbox.show(this.href,
            {title: 'Login',
            width: 500}
        );
    });
})
</pre><p>There&#8217;s some simple JS for when the user clicks the link a modal box opens up with the link&#8217;s href. Refer to the modalbox documentation if you&#8217;d like more customization. Here&#8217;s a screenshot:</p><div
class="tutorial_image"><img
id="initialmodalbox" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step1.png" alt="Initial Modalbox" title="" /></div><p>Notice that inside the modal box looks very similar to our standard page. Rails is using our application layout for all HTML responses. Since our XHR&#8217;s want HTML fragments, it make sense to render without layouts. Refer back to the example controller. I introduced a method for determining the layout. Add that to UserSessionsController to disable layout for XHR&#8217;s.</p><pre name="code" class="ruby">class UserSessionsController &lt; ApplicationController
  layout :choose_layout

  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])
    if @user_session.save
      flash[:notice] = "Login successful!"
      redirect_to user_path
    else
      render :action =&gt; :new
    end
  end

  def destroy
    current_user_session.destroy
    flash[:notice] = "Logout successful!"
    redirect_to root_path
  end

  private
  def choose_layout
    (request.xhr?) ? nil : 'application'
  end
end
</pre><p>Refresh the page and click the link you should get something like this:</p><div
class="tutorial_image"><img
id="withoutlayout" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step1-1.png" alt="Without Layout" title="" /></div><p>Fill in the form and see what happens. If you fill in the from with bad info, you&#8217;re redirected outside the modal box. If you login correctly you&#8217;re redirected normally. According the requirements the user should be able to fill out the form over and over again inside the modal box until they login correctly. How can we accomplish this? As described before we need to use AJAX to submit data to the server, then use JavaScript to update the modal box with the form or do a redirection. We know that the modalbox does a GET for HTML. After displaying the initial modalbox, we need to write JS that makes the form submits itself AJAX style. This allows the form to submit itself inside the modal box. Simply adding this code after the modal box is called won&#8217;t work because the XHR might not have finished. We need to use Modalbox&#8217;s afterLoad callback. Here&#8217;s the new code:</p><pre name="code" class="js">document.observe('dom:loaded', function() {
    $('login-link').observe('click', function(event) {
        event.stop();
        Modalbox.show(this.href,
            {title: 'Login',
            width: 500,
            afterLoad: function() {
                $('new_user_session').observe('submit', function(event) {
                    event.stop();
                    this.request();
                })
            }}
        );
    });
})
</pre><p>Form#request is a convenience method for serializing and submitting the form via an Ajax.Request to the URL of the form&#8217;s action attribute&#8212;which is exactly what we want. Now you can fill in the form inside the modal without it closing. The client side is now complete. What about the server side? The client is submitting a POST wanting JS back. The server needs to decide to either return JavaScript to update the form or render a redirect. In the UserSessionsController we&#8217;ll use respond_to to handle the JS request and a conditional to return the correct JS. Let&#8217;s begin by handling the failed login case. The server needs to return JS that updates the form, and tells the new form to submit over ajax. We&#8217;ll place this template in /app/views/users_sessions/create.js.erb. Here&#8217;s the structure for the new create action:</p><pre name="code" class="ruby">def create
  @user_session = UserSession.new(params[:user_session])
  if @user_session.save
    flash[:notice] = "Login successful!"
    redirect_to user_path
  else
    respond_to do |wants|
      wants.html { render :new }
      wants.js # create.js.erb
    end
  end
end
</pre><p>Now let&#8217;s fill in create.js.erb:</p><pre name="code" class="js">$('MB_content').update("&lt;%= escape_JavaScript(render :partial =&gt; 'form') %&gt;");
Modalbox.resizeToContent();
$('new_user_session').observe('submit', function(event) {
    event.stop();
    this.request();
});
</pre><p>First we update the content to include the new form. Then we resize the modal box. Next we ajaxify the form just as before. Voilla, you can fill in the form as many times as you want.</p><div
class="tutorial_image"><img
id="badinfo" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step2.png" alt="Bad Info" title="" /></div><div
class="tutorial_image"><img
id="updatedform" src="http://nettuts.s3.cdn.plus.org/568_login/prototype/step2-1.png" alt="Updated Form" title="" /></div><p>Next we need to handle the redirection case. Create a new file in /app/views/users_sessions/redirect.js.erb:</p><pre name="code" class="js">
  window.location=&#8221;&lt;%= user_path %>&#8221;;
</pre><p>Now, update the create action to handle the redirection process:</p><pre name="code" class="ruby">def create
  @user_session = UserSession.new(params[:user_session])
  if @user_session.save
    respond_to do |wants|
      wants.html do
        flash[:notice] = "Login successful!"
        redirect_to user_path
      end

      wants.js { render :redirect }
    end
  else
    respond_to do |wants|
      wants.html { render :new }
      wants.js # create.js.erb
    end
  end
end
</pre><p>And that&#8217;s it! Now try login with correct credentials and you&#8217;re redirected to the private page. For further learning, try to add a spinner and notification telling the user the form is submitting or they&#8217;re being redirect. The application still works if the user has JavaScript disabled too.</p><h1 id="jquery">jQuery</h1><p>Since I&#8217;ve already covered the Prototype process, so I won&#8217;t go into the same detail as before. Instead, I will move quickly describing the alternate JavaScript to add to the application. The jQuery vesion will have the exact same structure as the Prototype version. All we need to change is what&#8217;s in application.js, create.js.erb, and the JavaScript/css includes.</p><p>First thing we need to do is download <a
href="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js">jQuery</a> and <a
href="http://famspam.com/facebox/releases/facebox-1.2.tar.gz">Facebox</a>. Move jQuery into /public/JavaScripts as jquery.js. For facebox move the images into /public/images/, stylesheets into /public/stylesheets, and finally the JS into /public/JavaScripts. Now update /app/views/layouts/application.html.erb to reflect the changes:</p><pre name="code" class="ruby">&lt;head&gt;
  &lt;title&gt;&lt;%= h(yield(:title) || "Untitled") %&gt;&lt;/title&gt;
  &lt;%= stylesheet_link_tag 'facebox' %&gt;
  &lt;%= stylesheet_link_tag 'application' %&gt;
  &lt;%= JavaScript_include_tag 'jquery' %&gt;
  &lt;%= JavaScript_include_tag 'facebox' %&gt;
  &lt;%= JavaScript_include_tag 'application' %&gt;
&lt;/head&gt;
</pre><p>Facebox comes with a default stylesheet which assumes you have your images in /facebox. You&#8217;ll need to update these selectors in facebox.css like so:</p><pre name="code" class="css">#facebox .b {
  background:url(/images/b.png);
}

#facebox .tl {
  background:url(/images/tl.png);
}

#facebox .tr {
  background:url(/images/tr.png);
}

#facebox .bl {
  background:url(/images/bl.png);
}

#facebox .br {
  background:url(/images/br.png);
}
</pre><p>Now we attach facebox to the login link. Open up /public/JavaScripts/application.js and use this:</p><pre name="code" class="js">$(document).ready(function() {
    $('#login-link').facebox({
        loadingImage : '/images/loading.gif',
    closeImage   : '/images/closelabel.gif',
    });
});
</pre><p>I override the default settings for the images to reflect the new image path. Start the sever and head over to the index page. You should see a nice facebox with the login form:</p><div
class="tutorial_image"><img
id="facebox" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step1.png" alt="Facebox" title="" /></div><p>Next thing we have to do is set the form to submit itself via AJAX. Just like before, we&#8217;ll have to use callbacks to execute code after the modal box is ready. We&#8217;ll use jQuery&#8217;s post method for the XHR request. Facebox has an after reveal hook we can use. application.js:</p><pre name="code" class="js">$(document).ready(function() {
    $('#login-link').facebox({
        loadingImage : '/images/loading.gif',
        closeImage   : '/images/closelabel.gif',
    });

    $(document).bind('reveal.facebox', function() {
        $('#new_user_session').submit(function() {
            $.post(this.action, $(this).serialize(), null, "script");
            return false;
        });
    });
});
</pre><p>Updating create.js.erb should be easy enough. We have to update the facebox&#8217;s contents and re-ajaxify the form. Here&#8217;s the code:</p><pre name="code" class="js">$('#facebox .content').html("&lt;%= escape_JavaScript(render :partial =&gt; 'form') %&gt;");
$('#new_user_session').submit(function() {
    $.post(this.action, $(this).serialize(), null, "script");
    return false;
});
</pre><p>And that&#8217;s it! Here&#8217;s the final product:</p><div
class="tutorial_image"><img
id="loggingin" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step2.png" alt="Logging In" title="" /></div><div
class="tutorial_image"><img
id="badlogin" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step2-1.png" alt="Bad Login" title="" /></div><div
class="tutorial_image"><img
id="redirected" src="http://nettuts.s3.cdn.plus.org/568_login/jquery/step2-2.png" alt="Redirected" title="" /></div><h3 id="gettingthecode">Downloading the Code</h3><p>You can get the code <a
href="http://github.com/Adman65/Unobtrusive-Login/">here</a>. There are branches for each library so you can check out the Prototype or jQuery versions. Any questions, comments, concerns? Thanks again for reading!</p><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/ruby/how-to-build-an-unobtrusive-login-system-in-rails/feed/</wfw:commentRss> <slash:comments>17</slash:comments> </item> <item><title>24 Best Practices for AJAX Implementations</title><link>http://net.tutsplus.com/tutorials/javascript-ajax/24-best-practices-for-ajax-implementations/</link> <comments>http://net.tutsplus.com/tutorials/javascript-ajax/24-best-practices-for-ajax-implementations/#comments</comments> <pubDate>Mon, 08 Feb 2010 18:42:47 +0000</pubDate> <dc:creator>Siddharth</dc:creator> <category><![CDATA[JavaScript & AJAX]]></category> <category><![CDATA[AJAX]]></category> <category><![CDATA[best practices]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9180</guid> <description><![CDATA[<img
src="http://nettuts.s3.amazonaws.com/567_ajaxImplementation/images/200x200.jpg" alt="24 Best Practices for AJAX Implementations" />]]></description> <content:encoded><![CDATA[<p>Implementing AJAX technology can be a hit or miss thing. Do it well and you&#8217;ll have users raving over the slickness it provides to the general user experience while if you mess it up, you&#8217;ll be at the receiving end of their wrath. Here are 24 tips to guide you with implementing AJAX technology within your web application.</p><p><span
id="more-9180"></span></p><h3>1. Understand What it All Means</h3><p>First up, you need to understand what AJAX is, what it stands for and how it has revolutionized parts of the internet. You&#8217;ll need to know what its advantages are before you can make an informed decision</p><p>Here is a list of must read articles to get you up to speed.</p><ul><li><a
href="http://en.wikipedia.org/wiki/Ajax_%28programming%29">WikiPedia</a></li><li><a
href="https://developer.mozilla.org/En/AJAX">MDC on AJAX</a></li><li><a
href="http://www.devx.com/webdev/Article/28456">DevX</a></li></ul><h3>2. Check for Appropriate Usage Scenarios</h3><p>AJAX can sound all fine and dandy but there are only so many places you can implement it without it sounding like another bullet point. Do proper research and testing to make sure you are implementing AJAX for the right reasons. Because it sounds nice is not a valid reason.</p><p>Proper usage scenarios would be if you have lots of data in the back end and want to update the UI as and when the user needs access to that data or when you want to emulate a proper desktop application and handle everything asynchronously. An extremely bad scenario is when you have each page of a static web site load through AJAX for no reason other than you can. Use your discretion here.</p><h3>3. Learn to Implement it With Raw Code</h3><p>Before you delve into writing your code, understand the raw code to do it first. Libraries are great at reducing the time it takes to create browser agnostic code but when it breaks it&#8217;d be best if you know how to do it without libraries helping you.</p><p>I highly recommend Jeffrey&#8217;s tutorials on making AJAX requests with raw JavaScript <a
href="http://net.tutsplus.com/videos/screencasts/how-to-make-ajax-requests-with-raw-javascript/">here</a> and <a
href="http://net.tutsplus.com/videos/screencasts/how-to-make-ajax-requests-with-raw-javascript-part-2/">here</a>.</p><h3>4. Use a Library</h3><p>Once you&#8217;ve mastered the raw JS which handles the AJAX implementations, it&#8217;s best you shift over to a JavaScript library which provides robust support for AJAX. Any of the major libraries like jQuery, Prototype or MooTools should do.</p><p>Libraries not only provide an exhaustive feature set you can make use of but also makes sure your code is compatible with all browsers without you having to do anything extra.</p><p>Here are a few of our favorites which encompass proper AJAX functionality:</p><ul><li><a
href="http://jquery.com/">jQuery</a></li><li><a
href="http://dojotoolkit.org/">Dojo</a></li><li><a
href="http://mootools.net/">MooTools</a></li><li><a
href="http://prototypejs.org/">Prototype</a></li><li><a
href="http://developer.yahoo.com/yui/">Yahoo Ui Library</a></li><li><a
href="http://code.google.com/webtoolkit">Google Web Toolkit</a></li></ul><h3>5. Master the Library</h3><p>Once you&#8217;ve gotten the hang of making AJAX requests with your library of choice, it&#8217;s time to take it to the next level and master it. It may sound a little redundant but there is a big difference between the two.</p><p>With each library getting bigger, packing more features with each release, the developers hide a huge amount of functionality from the beginner developer. For example, did you know that there are <a
href="http://net.tutsplus.com/tutorials/javascript-ajax/5-ways-to-make-ajax-calls-with-jquery/">multiple methods</a> in jQuery to make AJAX calls? Or that a number of event triggered methods are only available with the core AJAX call? A lot of people don&#8217;t know that and thus are unable to leverage the untapped potential of the library.</p><p>Here are a few choice resources for your perusal:</p><ul><li><a
href="http://www.packtpub.com/jquery-1-4-reference-guide/book">jQuery 1.4 Reference Guide </a></li><li><a
href="http://jqueryenlightenment.com/">jQuery Enlightenment</a></li><li><a
href="http://www.learningjquery.com/category/levels/advanced">Learning jQuery&#8217;d Advanced section</a></li><li><a
href="http://jqueryvsmootools.com/">A comparison between jQuery and MooTools</a></li></ul><h3>6. Provide Feedback</h3><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/567_ajaxImplementation/images/gmail.jpg" alt="Tutorial Image" border="0" /></div><p>On of the main reasons people were against AJAX in the past was they couldn&#8217;t really tell when the application updates the data it contains. This is also an integral part of the general user experience made even more pertinent with AJAX.</p><p>So even for the tiniest thing, remember to provide feedback to the user letting them know their action has been registered. The user has clicked on a button? Let them know!</p><h3>7. Utilize Proper Events and Callback Functions</h3><p>Whether you are using raw JS or a library to implement this functionality, you&#8217;ll have access to the state of the request i.e. whether the request was successful; met with an error and finally whether it has been completed.</p><p>Make proper use of these events and their respective callbacks to manipulate the UI for a better user experience. For example, if the request was unsuccessful, you&#8217;d want to update the user interface to reflect that their changes weren&#8217;t successful while if it was successful, you&#8217;d want to tell them so. Don&#8217;t keep the user waiting!</p><p>With jQuery, you&#8217;d make use of the <em>success</em> and <em>error</em> callbacks. You also get other callbacks such as <em>complete</em> and <em>beforeSend</em> to be invoked for apporopriate use.</p><pre class="js" name="code">
$.ajax({
        //Other code
           success: function(msg)
        {
            // Update the UI here to reflect that the request was successful.
            doSomethingClever();
        },
        error: function(msg)
        {
            // Update the UI here to reflect that the request was unsuccessful
            doSomethingMoreClever();
        },
        complete: function(msg)
        {
            // Update the UI here to reflect completion
            doSomethingEvenMoreClever();
        }
});
</pre><p>- Show quoted text -</p><h3>8. Choose the Right Format for the Job</h3><p>Just because XML occurs in the abbreviation doesn&#8217;t mean you are limited to XML for the payload. You are free to choose whatever format strikes your liking. JSON? Sure. XML? Naturally. HTML? Of course. Raw strings? Definitely.</p><p>So, essentially, whatever floats your boat. You aren&#8217;t limited to any format. You get to choose whichever format makes the work at hand easier for you and makes the most sense for that specific instance.</p><h3>9. Read Extensively</h3><p>AJAX, while old in relative terms, is still very much in flux. Exciting new solutions are created everyday while scarily thorough books covering the subject are often released. Be it web developments blogs (like this one!) or books, keep reading to keep yourself informed of the latest developments.</p><p>Here are my most visited and/or read blogs and books:</p><ul><li><a
href="http://css-tricks.com/">CSS Tricks</a></li><li><a
href="http://snook.ca/">Snook.ca</a></li><li><a
href="http://james.padolsey.com/">James Padolsey&#8217;s Blog</a></li><li><a
href="http://remysharp.com/">Remy Sharp&#8217;s Blog</a></li></ul><h3>10. Experiment Continuously</h3><p>Reading book after book and article after article is awesome but to get a grip on the subject, you&#8217;ll need to fold up your sleeves  and write some code yourselves. Trust me, you&#8217;ll learn a lot more a lot quicker reading a bit and then writing some code about it than just reading continuously without writing any code to better understand what you&#8217;ve learnt.</p><h3>11. Utilize Firebug</h3><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/567_ajaxImplementation/images/firebug.png" alt="Tutorial Image" border="0" /></div><p>Firebug is arguable the most important tool in every web developer&#8217;s repertoire. Along with impressive JavaScript debugging and other potent features, it also let&#8217;s you see each AJAX request as it is made along with a myriad other details about the request including from where it originates, what its payload is and so much more. You can download it right here.</p><p>Here are a few more recommended resources:</p><ul><li><a
href="http://net.tutsplus.com/tutorials/other/10-reasons-why-you-should-be-using-firebug/">10 Reasons Why You Should Be Using Firebug</a></li><li><a
href="http://net.tutsplus.com/tutorials/plus-tutorials-2/firebug-white-to-black-belt-new-plus-tutorial/">Firebug Explained</a></li><li><a
href="http://www.kristarella.com/2009/02/how-to-use-firebug-for-css/">How to Use Firebug with CSS</a></li><li><a
href="http://www.tutorial9.net/web-tutorials/quick-easy-css-development-with-firebug/">Easy CSS with Firebug</a></li></ul><h3>12. Keep the Users With Old Browsers in Mind</h3><p>Unless your web application is like Google Maps it&#8217;s always a good idea to provide users with a fallback so they can still use your application. Case in point would be the numerous web applications which route all their user interactions through AJAX if they have the capability while falling back to a normal HTML version otherwise.</p><h3>13. Bookmarkability</h3><p>The tendency to bookmark is a pervasive habit of the average web user and it&#8217;s imperative your application respects that. With AJAX, the address bar of the browser is not updated which means when a user wants to bookmark a page with content loaded dynamically with AJAX, he/she is going to bookmark the initial page and not the updated page. This presents a huge problem.</p><p>Fortunately, there are a few techniques to fix this problem. Here is a selected list of articles intended to help you with that:</p><ul><li><a
href="http://www.contentwithstyle.co.uk/content/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps">Content with Style</a></li><li><a
href="http://www.mikage.to/jquery/jquery_history.html">jQuery History Plugin</a></li><li><a
href="http://code.google.com/p/reallysimplehistory/">Really Simple History</a></li></ul><h3>14. Use Proper Animations</h3><p>This is another of those user experience issues which may mar an otherwise spectacular application. Often with an AJAX application, the user may fail to even notice a change has occurred with an element of the user interface or the data it contains. In light of this issue, it&#8217;s essential that the developer uses non-garish, tasteful animations to draw the user&#8217;s attention to the fact that the user interface has been updated to reflect the user&#8217;s actions.</p><p>You can read about how to use jQuery to create tasteful, cross browser animations <a
href="http://net.tutsplus.com/tutorials/javascript-ajax/jquery-animations-a-7-step-program/">here</a>.</p><h3>15. Respect the Back Button</h3><p>The back button is another action that has become part of a normal web user&#8217;s habits. Make sure your application adheres to this respected paradigm to avoid angering users. Trust me, they will, if suddenly their back button doesn&#8217;t work as intended.</p><p>Here is a list of article which should help you with the matter.</p><ul><li><a
href="http://www.contentwithstyle.co.uk/content/fixing-the-back-button-and-enabling-bookmarking-for-ajax-apps">Content with Style</a></li><li><a
href="http://www.mikage.to/jquery/jquery_history.html">jQuery History Plugin</a></li><li><a
href="http://code.google.com/p/reallysimplehistory/">Really Simple History</a></li></ul><h3>16. Change the DOM Intelligently</h3><p>Imagine this: your request has succeeded and has returned a chunk of data with which you hope to update your user interface. If this chunk of data has few individual chunks, you can proceed as usual. If instead it has, say, 15 contiguous elements to be updated, it is better to just create the elements, modify their data in memory and replace those in the DOM in one big swoop rather than accessing each element and updating the DOM each time separately.</p><p>Modifying the DOM separately leads to worse performance as the number of edits to be made increases.</p><p>So, for a chunk of HTML like so:</p><pre class="js" name="code">
&lt;div id="container"&gt;
&lt;span id="elem1"&gt;&lt;/span&gt;
&lt;span id="elem2"&gt;&lt;/span&gt;
&lt;/div&gt;
</pre><p>instead of doing this:</p><pre class="js" name="code">
$("#elem1").html("Value 1");
$("#elem2").html("Value 2");
</pre><p>Do this:</p><pre class="js" name="code">
var updatedText = "&lt;span id=\"elem1\"&gt;Value1&lt;/span&gt;
&lt;span id=\"elem2\"&gt;Value2&lt;/span&gt;";
$("#container").html(updatedText);
</pre><p>It might look a lot of work for just two elements but once you extrapolate it to more, the performance alone will be worth it. It&#8217;ll be faster since you&#8217;ll be updating the DOM just once irrespective of how many elements you have within the updated HTML. With the usual method though, the number of edits required to the DOM scales linearly to the number of elements which in turn degrades performance.</p><h3>17. Comment Your Code</h3><p>This is a no-brainer but comment your code properly. Chances are, your code is going to be looked at by a few hundred people , at least, looking to learn from you and commenting is definitely going to earn your extra rep points and paragon cookies.</p><p>You don&#8217;t necessarily need to comment every tiny bit of your code; commenting just the important bits is sufficient.</p><p>This is too much!</p><pre class="js" name="code">
$.ajax({
    // Switch off caching
    cache: false,

        //Set the type of request
       type: "GET",

        // Set the timeout
    timeout: 5000,

        // Specify the proper handler
       url: "handler.php",
       success: function(msg)
        {
           // Update the UI here to reflect that the request was successful.
           doSomethingClever();
        },
        error: function(msg)
        {
           // Update the UI here to reflect that the request was unsuccessful
           doSomethingMoreClever();
        }
});
</pre><p>A much better way to add comments since a lot of it is self explanatory.</p><pre class="js" name="code">

// Make an AJAX call to handler.php and update the UI
$.ajax({
    cache: false,
       type: "GET",
    timeout: 5000,
       url: "handler.php",
       success: function(msg)
        {
           doSomethingClever();
        },
        error: function(msg)
        {
              doSomethingMoreClever();
        }
});
</pre><h3>18. Make an Informed Decision About the Request Type</h3><p>This is strictly a general web application tip than specifically an AJAX tip but do take special note of the type of request you are making: GET or POST. The XMLHttpRequest object is capable of making both type of requests but it is up to you to decide what kind to make.</p><p>As their names signify, a GET request is used to procure data from a source while a POST request is used to submit data to be processed. With an AJAX GET request, as with a normal GET request, you&#8217;ll have to pass on the query data as part of the URL itself manually as opposed to a POST request where the data is sent automatically. Also note that GET requests are cached automatically while a POST request isn&#8217;t.</p><h3>19. Use a Proper IDE</h3><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/567_ajaxImplementation/images/coda.jpg" alt="Tutorial Image" border="0" /></div><p>When it comes to JavaScript, please don&#8217;t be an elitist and limit yourself to plain old notepad. Your productivity will spike sharply with the use of a proper IDE, specially one with support for your JavaScript library of choice.</p><h4>For the PC loyalists</h4><ul><li><strong><a
href="http://intype.info/home/index.php">InType</a></strong></li><li><strong><a
href="http://www.e-texteditor.com/">E-Text Editor</a></strong></li><li><strong><a
href="http://notepad-plus.sourceforge.net/uk/site.htm">Notepad++</a></strong></li><li><strong><a
href="http://www.aptana.com">Aptana</a></strong></li><li><strong><a
href="http://www.adobe.com/products/dreamweaver/">Dreamweaver CS4</a></strong></li></ul><h4>For my fruit flavored brethren</h4><ul><li><strong><a
href="http://www.panic.com/coda">Coda</a></strong></li><li><strong><a
href="http://macrabbit.com/espresso/">Espresso</a></strong></li><li><strong><a<br
/> href="http://macromates.com/">TextMate</a></strong></li><li><strong><a<br
/> href="http://www.aptana.com">Aptana</a></strong></li><li><strong><a<br
/> href="http://www.adobe.com/products/dreamweaver/">DreamWeaver CS4</a></strong></li></ul><h3>20. Participate in the Community</h3><p>Getting to be a part of awesome web development communities, like this, will not only expose you to a wider range of ideas but will also lead you to the path of writing better code. By writing and commenting on articles similar to these, you&#8217;ll not only teach people less knowledgeable than you on the subject but you&#8217;ll also be able to learn more from the more experienced people who comment on your code.</p><p>As Jeff says, you only truly understand something when you&#8217;ve taught it to someone else.</p><h3>21. Tweak Your Response Times</h3><p>By response time I mean only one thing: the time before a user triggers an AJAX request. Consider this, you are typing in an input box which uses AJAX to retrieve search suggestions from the server. Response time would be the time duration between the key press and the AJAX call being made. Too fast and you&#8217;d have to do multiple requests for each letter of the search phrase. Too slow and you&#8217;ll have the user twiddling his thumbs wondering as to how he broke the application.</p><p>This isn&#8217;t limited to just the scenario noted above. This applies to each and every non-definite (click) user action. Test rigorously with your users to find the optimum latency.</p><h3>22. Use Status Indicators</h3><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/567_ajaxImplementation/images/loading.jpg" alt="Tutorial Image" border="0" /></div><p>This is an extension of a point noted above but just as important. Users coming from the desktop application or a general web application paradigm will be flummoxed when they use an AJAX enabled web application. While notifying the user when a change has been made is good, you&#8217;ll also need to make sure to let them know that a request has been initiated in the first place.</p><p>This is where status indicators come in. These are the little rotating or bouncing GIFs you see in applications. In function these are similar to the hour glass cursor used in desktop operating systems.</p><p><a
href="http://www.ajaxload.info/">Here</a> is a wonderful little tool which lets you create an indicator of your choice.</p><h3>23. Appreciate JSON-P&#8217;s Awesomeness</h3><p>Often, as part of the cross site mashup you&#8217;re creating, you&#8217;d need to access data from other sites through AJAX requests. This flies directly in the face of the cross domain restriction most browsers enforce. In this case, instead of going with exotic solutions like masking and proxying, you could just use JSON-P.</p><p>JSON-P, JSON with Padding, essentially lets us circumvent this restriction and lets us obtain data from third party domains. Here is a list of articles to get you started:</p><ul><li><a
href="http://en.wikipedia.org/wiki/JSON#JSONP">WikiPedia Link</a></li><li><a
href="http://remysharp.com/2007/10/08/what-is-jsonp/">Remy Sharp&#8217;s Blog</a></li><li><a
href="http://james.padolsey.com/javascript/using-yql-with-jsonp/">James Padolsey&#8217;s Blog</a></li></ul><h3>24. Ask Questions Freely</h3><p>Don&#8217;t be shy to ask questions. Every one of us started as a complete newbie and began by asking questions. There are plenty of placed to clarify your doubts including the comments section of Nettuts+. Never, ever be afraid of asking questions. Just try to be a little polite! It always helps.</p><h3>That&#8217;s all folks</h3><p>And we&#8217;re done. Twenty four points to keep in mind when implementing AJAX within your site or web application. Hopefully, this has been useful to you and you found it interesting. I&#8217;ll be closely watching the comments section so chime in there if you have any counter arguments or different perspectives on the matter.</p><p>Questions? Nice things to say? Criticisms? Hit the comments section and leave me a comment. Happy coding!</p><h3>Write a Plus Tutorial</h3><p><strong>Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? </strong>We&#8217;re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you&#8217;re of the ability, please contact Jeffrey at nettuts@tutsplus.com.</p><p>Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.</p><div
class="tutorial_image"><a
href="http://tutsplus.com/plus-program/net-plus/"><img
src="http://miscfiles.s3.amazonaws.com/banners/nettuts_728x90.jpg" alt="Write a PLUS tutorial" style="width:600px;" /></a></div><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/24-best-practices-for-ajax-implementations/feed/</wfw:commentRss> <slash:comments>55</slash:comments> </item> <item><title>Quick Tip: How to Extend Built-in Objects in JavaScript</title><link>http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-how-to-extend-built-in-objects-in-javascript/</link> <comments>http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-how-to-extend-built-in-objects-in-javascript/#comments</comments> <pubDate>Fri, 05 Feb 2010 21:30:20 +0000</pubDate> <dc:creator>Jeffrey Way</dc:creator> <category><![CDATA[JavaScript & AJAX]]></category> <category><![CDATA[Screencasts]]></category> <category><![CDATA[constructor functions]]></category> <category><![CDATA[extending functions]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9168</guid> <description><![CDATA[<img
src="http://nettuts.s3.amazonaws.com/566_augmentObjects/200x200.png" alt="Quick Tip: How to Extend Built-in Objects in JavaScript" />]]></description> <content:encoded><![CDATA[<p> Constructor functions, like <a
href="http://www.w3schools.com/jsref/jsref_obj_array.asp">Array</a>, offer a wide range of methods and properties that you can make use of. But have ever wished that one of these objects offered some method that isn&#8217;t built-in? Is there a way to do so yourself? Absolutely! Let&#8217;s see how.</p><p><span
id="more-9168"></span></p><div
class="tutorial_image"> <object
classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='600' height='369'><param
name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param
name='flashvars' value='i=44891' /><param
name='allowFullScreen' value='true' /><embed
src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=44891' allowFullScreen='true' width='600' height='369' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></div><h3>Reversing a String</h3><p> This little snippet takes advantage of the Array object&#8217;s &#8220;reverse&#8221; method, and applies its functionality to a given string. In effect, something like &#8220;hello&#8221; will be turned into &#8220;olleh,&#8221; and can be accessed by using &#8220;myString.reverse()&#8221;.</p><pre name="code" class="js">
String.prototype.reverse = function() {
	return Array.prototype.reverse.apply(this.split('')).join('');
};

var myString = 'hello';
console.log(myString.reverse());
</pre><h3>Bonus Question</h3><p> Now that we have a basic of understanding of augmenting objects, can you figure out a way to write a custom &#8220;contains&#8221; method for the String object? For example, the jQuery library allows us to write things like:</p><pre name="code" class="js">
$("div:contains('John')").css('fontWeight', 'bold');
</pre><p>The <a
href="http://api.jquery.com/contains-selector/">snippet</a> above will search through all of the divs on the page, and then filter that wrapped set down to only those that contain the string &#8220;John.&#8221; How could we extend the String object, with raw JavaScript, to allow for this? Leave your solution in the comments, and we&#8217;ll discuss!</p><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-how-to-extend-built-in-objects-in-javascript/feed/</wfw:commentRss> <slash:comments>42</slash:comments> </item> <item><title>What&#8217;s Changed in jQuery UI 1.8 &#8211; Plus Free Books!</title><link>http://net.tutsplus.com/tutorials/javascript-ajax/whats-changed-in-jquery-ui-1-8-plus-free-books/</link> <comments>http://net.tutsplus.com/tutorials/javascript-ajax/whats-changed-in-jquery-ui-1-8-plus-free-books/#comments</comments> <pubDate>Fri, 05 Feb 2010 19:43:23 +0000</pubDate> <dc:creator>Dan Wellman</dc:creator> <category><![CDATA[JavaScript & AJAX]]></category> <category><![CDATA[jQuery]]></category> <category><![CDATA[jQuery ui]]></category> <category><![CDATA[jquery ui 1.8]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9150</guid> <description><![CDATA[<img
src="http://nettuts.s3.amazonaws.com/565_jqueryUI/200x200.jpg" alt="What's In Store for jQuery UI 1.8 - Plus Free Books!" />]]></description> <content:encoded><![CDATA[<p><a
href="http://jqueryui.com/">jQuery UI 1.8</a> is currently at the release candidate stage and, barring the discovery of a major bug or flaw, will shortly become the current stable release of jQuery&#8217;s official UI library. So what has changed since the last current stable release of 1.7.2? One of the major differences of course is that the library now runs on the latest release of <a
href="http://www.jquery.com">jQuery</a> itself &#8211; version 1.4.1, but there have been many other changes including the addition of some great new components, which we&#8217;ll look at over the course of this article.</p><p><span
id="more-9150"></span></p><h3>Free Copies of jQuery UI 1.7</h3><p> The author of this article, <a
href="http://danwellman.co.uk/">Dan Wellman</a>, recently released <a
href="http://www.packtpub.com/user-interface-library-for-jquery-ui-1-7/book">jQuery UI 1.7</a>, from <a
href="http://www.packtpub.com/index">Packt Publishing</a>. It&#8217;s a fantastic read, and I&#8217;m pleased to announce that we have a handful of copies to randomly give out. Simply leave a comment about the article, and you&#8217;ll automatically be entered into the drawing. Check back on Monday to find out if you&#8217;re a winner!</p><div
class="tutorial_image"> <a
href="http://www.packtpub.com/user-interface-library-for-jquery-ui-1-7/book"><img
src="http://nettuts.s3.amazonaws.com/565_jqueryUI/jqueryui.jpg" alt="jQuery UI 1.7" /></a></div><style type="text/css">/*<![CDATA[*/dt strong {
 font-size: 16px;
margin-bottom: 14px;
}</p>
<p>dd {
 margin-bottom: 15px;
}/*]]>*/</style><h2>Bug Zapping</h2><p>This release of the library brings several bug fixes for some key components including the Datepicker and Dialog widgets and the Droppable, Resizable and Selectable interaction helpers. None of the bugs were show-stoppers, but nevertheless, clearing out the bugs is a critical part of the ongoing progression of the library. One important point to note is that the <strong>beforeclose</strong> event of the Dialog widget has been deprecated and replaced with <strong>beforeClose</strong> so that it follows the same naming convention as the events of other components.</p><p>As well as bugs in the code, several styling and accessibility issues have also been addressed; notably the title text of Dialog widgets can no longer disappear behind the close icon, and the keyboard navigability of the new button widget has been improved. For a complete list of all bug fixes included with version 1.8 see the changelog at <a
href="http://jqueryui.com/docs/Changelog/1.8rc1">http://jqueryui.com/docs/Changelog/1.8rc1</a></p><h2>Positioning</h2><p>jQuery UI now has a unique positioning system that that can be used whenever a widget needs to be positioned relative to another element, such as with a drop-down menu or a floating tooltip. The Position utility allows us to easily specify, using a series of simple strings, which part of the positioned element should be fixed to which part of the specified target element. So for example, the <strong>&#8220;top left&#8221;</strong> point of one element can be fixed to the <strong>&#8220;bottom right&#8221;</strong> of another specified element.</p><p>The utility also features a robust collision detection system which prevents viewers of the page being exposed to unsightly toolbars if the element being positioned gets too close to the edge of the viewport, or cannot otherwise occupy its positioned place.</p><p>The API for this utility is compact, with just 7 configurable options at this stage. This gives us all the control we need however and allows us to specify up to <strong>81</strong> possible combinations of positioning; options we can configure include the following:</p><dl><dt><strong>at</strong>:</dt><dd>Refers to the position on the target element the element being positioned will be fixed to; the method accepts a single string comprised of the value for the horizontal axis (either <strong>right</strong>, <strong>center</strong>, or <strong>left</strong>) followed by the value for the vertical axis (either <strong>top</strong>, <strong>center</strong>, or <strong>bottom</strong>). There is no separating character between the 2 values.</dd><dt
style="margin-top: 15px;"><strong>bgiframe</strong>:</dt><dd>If the bgiframe plugin is available on the page, this option will apply an iframe shim to the positioned element, which can help to prevent select elements showing above the positioned content in IE6.</dd><dt><strong>collision</strong>:</dt><dd>This option determines how collisions are handled; it accepts one of the following strings: <strong>flip</strong>, <strong>fit</strong> or <strong>none</strong>. The default is <strong>flip</strong>, which causes the element being positioned to invert the position relative to the target element, e.g. <strong>&#8220;right center&#8221;</strong> will become <strong>&#8220;left center&#8221;</strong>.</dd><dt><strong>my</strong>:</dt><dd>Refers to the element being positioned; accepts same values as <strong>at</strong>.</dd><dt><strong>of</strong>:</dt><dd>Accepts a jQuery selector specifying the target element.</dd><dt><strong>offset</strong>:</dt><dd>Specify a number of pixels to offset the element being positioned on the target element.</dd><dt><strong>using</strong>:</dt><dd>A callback function can be used with this option allowing you to animate the positioning of the element.</dd></dl><h2>Autocomplete</h2><p>One of my favourite widgets has returned as an official UI component! Autocomplete was a beta widget in an early 1.6 version of the library and is now back after a complete refactor. It is attached to text inputs on the page and supplies a list of possible choices when a visitor begins typing in the text field.</p><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/565_jqueryUI/img1.jpg"></div><p>The widget can take its data (the matching items in the suggestion menu) from a variety of sources including a standard JavaScript array, JSON via an AJAX request or a flexible callback function that can implement any data source and return a customized response to display in the suggestion menu.</p><p>Autocomplete is a highly configurable widget and features a full API of options, methods and events to make use of. It&#8217;s completely themable via SteamRoller and fully keyboard navigable. All in all this component brings a lot of functionality to your pages. At some future point caching may also be a configurable behaviour.</p><p>Let&#8217;s take a look at its API; it contains the following three configuration options:</p><dl><dt><strong>delay</strong>:</dt><dd>We can specify the number of milliseconds the widget should wait before displaying the suggestion menu when the visitor begins typing in the input.</dd><dt><strong>minLength</strong>:</dt><dd>This option takes an integer that refers to how many characters should be typed into the input before the suggestion menu is displayed.</dd><dt><strong>source</strong>:</dt><dd>We configure the data source using this option; possible values include an array of strings representing the items to show in the suggestion menu, or an array of objects where each 	object contains two properties &#8211; the first is the label shown in the suggestion menu, the 	second is the value that will be added to the input if an item in the suggestion menu is 	selected.  We can also supply a single string representing a remote resource that can return the data asynchronously, or a callback function that can request the data and return it to the widget in the required format.</dd></dl><p>The following two methods are exposed by Autocomplete:</p><dl><dt><strong>close</strong>:</dt><dd>Used to close the suggestion menu.</dd><dt><strong>search</strong>:</dt><dd>Perform a search of the available data and display the suggestions if the term is matched.	Can take a predefined value as the term which is passed into the method as an argument, or the value of the input field it is associated with.</dd></dl><p>We can also hook callback functions into the following custom events:</p><dl><dt><strong>change</strong>:</dt><dd>Fired after an item in the suggestion menu is selected and the menu is closed.</dd><dt><strong>close</strong>:</dt><dd>Fired whenever the suggestion menu is closed, whether or not an item was selected. Precedes the <strong>change</strong> event.</dd><dt><strong>focus</strong>:</dt><dd>Fired directly before focus is given to an item in the suggestion menu.</dd><dt><strong>open</strong>:</dt><dd>Fired once the data has been returned, directly before the suggestion menu is displayed.</dd><dt><strong>search</strong>:</dt><dd>Fired directly before the data source is searched. The search can be cancelled by returning <strong>false</strong> from a callback function bound to this event.</dd><dt><strong>select</strong>:</dt><dd>This event is triggered when an item from the menu before the menu closes.</dd></dl><p>As a special bonus, the source file for the Autocomplete widget also contains the beta Menu widget, which is still currently in development and is due for release in a later version of the library. So far it looks like a robust and attractive addition to the library, and allows us to transform an unordered list into an attractive drop-down or fly-out menu. Many features are supported including sub-menus, icons, dividers and even a drill-down menu with breadcrumb.</p><h2>Button</h2><p>The button widget allows us to implement attractive and functional buttons that can be configured to behave like a particular type of button; for example, we can crate standard push buttons, radio-style buttons where only a single button in a set may be selected, or check-style buttons where any number in a particular set may be selected. Several types of button that incorporate a simple drop-down menu can also be created.</p><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/565_jqueryUI/img2.jpg"></div><p>It&#8217;s a very flexible widget and can be built using a variety of underlying elements including <strong>&lt;button></strong>, <strong>&lt;input></strong> and <strong>&lt;a></strong>. The buttons are fully accessible and ARIA compliant, adding or removing the appropriate roles and states when necessary. The API is relatively simple at this point, but covers all essentials with three configurable options and a single method to invoke; the configuration options are as follows:</p><dl><dt><strong>icons</strong>:</dt><dd>This option allows us to specify primary and secondary icons to display on the button. It expects an object with the keys <strong>primary</strong> and <strong>secondary</strong>, and CSS class names as the values.</dd><dt><strong>label</strong>:</dt><dd>With this option we can set the text that is displayed on the button; a string value is expected, but if this is not supplied the value of the underlying HTML element from which the button is created can be used.</dd><dt><strong>text</strong>:</dt><dd>The text option accepts a Boolean indicating whether or not to show a text label on the button, which could be the case if a simple icon is all that is needed. The default value is <strong>true</strong>.</dd></dl><p>The event that we can bind to in order to execute a callback function and react to interaction is the <strong>click</strong> event; the native <strong>click</strong> event of the browser is used unless with the radio or checkbox-style buttons, in which case the event is fired by the widget, not the underlying element.</p><h2>Mouse Utility</h2><p>The final new utility to be found in jQuery UI 1.8 is the Mouse utility, which is used by other library components in order to better distribute related implementations of the same behaviour by different widgets. This is great for developers because it means that if mouse interaction is a required behaviour of a custom UI widget, the logic in this utility can be used without having to rewrite it manually. Like the Menu component however, this utility should be considered beta and subject to considerable revision in future releases.</p><p>The API is very compact; there are just three configurable options; there are a series of private methods that are used internally by the plugin, but nothing we would need to manually invoke. The configurable options are as follows:</p><dl><dt><strong>cancel</strong>:</dt><dd>This option accepts a string value containing selectors and allows us to configure elements that interaction should be cancelled on. The default value is <strong>&#8216;:input, option&#8217;</strong> so for example, in a drag and drop implementation, these elements would not be draggable.</dd><dt><strong>distance</strong>:</dt><dd>This option accepts an integer representing the number of pixels the mouse should move before the interaction is registered. The default is <strong>1</strong>.</dd><dt><strong>delay</strong>:</dt><dd>This option also accepts an integer, but this time refers to the number of milliseconds that should elapse before the interaction is registered. The default of this option is <strong>0</strong>.</dd></dl><h2>Summary</h2><p>jQuery UI 1.8 is shaping up to be a fine release of the library; with a combination of both bug-fixes and new components it&#8217;s looking like an important milestone in the library&#8217;s roadmap. We first looked at the library&#8217;s new positioning system which gives us easy access to a huge number of different was of positioning one element relative to another element. We then looked at the two new components Autocomplete and Button and saw the different configuration options, methods and events exposed by each of their APIs.</p><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/whats-changed-in-jquery-ui-1-8-plus-free-books/feed/</wfw:commentRss> <slash:comments>384</slash:comments> </item> <item><title>Working with RESTful Services in CodeIgniter</title><link>http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/</link> <comments>http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/#comments</comments> <pubDate>Thu, 04 Feb 2010 13:47:10 +0000</pubDate> <dc:creator>Philip Sturgeon</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[codeigniter]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[php framework]]></category> <category><![CDATA[rest]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=8814</guid> <description><![CDATA[<img
src="http://nettuts.s3.cdn.plus.org/183_codeIgniter/200x200.png" alt="preview" width="200" height="200"/>]]></description> <content:encoded><![CDATA[<p><a
href="http://www.codeigniter.com">CodeIgniter</a> is becoming well known for its power as a PHP based web application framework, but it&#8217;s not often that we see examples of it being used for anything else. Today we&#8217;ll learn how we can use CodeIgniter to create a RESTful API for your existing web applications, and demonstrate how to interact with your own API or other RESTful web-services, such as Facebook and Twitter.</p><p><span
id="more-8814"></span></p><h3>Tutorial Details</h3><ul><li><b>Program</b>: CodeIgniter, <a
href="http://github.com/philsturgeon/codeigniter-restserver">CodeIgniter REST server</a> and <a
href="http://github.com/philsturgeon/codeigniter-restclient">CodeIgniter REST client</a></li><li><b>Difficulty:</b> Medium</li><li><b>Estimated Completion Time:</b> 30 minutes</li></ul><h3>Introduction</h3><p>If you have been following the <em><a
href="http://net.tutsplus.com/videos/screencasts/codeigniter-from-scratch-day-7-pagination/">CodeIgniter From Scratch</a></em> series you will know by now that it is relatively quick and easy to put together simple web applications, such as blogs, CMS systems, brochure sites, etc. One thing you may not have thought about is using CodeIgniter to create an interactive API. After trying several existing REST implementations, I found they not only lacked simplicity but were missing most of the features you would expect from a RESTful implementation; so I built my own. This tutorial will show you how to use this code to set up your REST API, and gives example of how to interact with it from your web application.</p><h3>Assumptions</h3><ol><li>You have a web server set up, locally or online and known how to manage files on it.</li><li>You have read a few of the <a
href="http://net.tutsplus.com/videos/screencasts/codeigniter-from-scratch-day-7-pagination/">CodeIgniter from Scratch</a> tutorials.</li><li>You know how to set up CodeIgniter.</li><li>You know a little about RESTful services.</li></ol><p>This tutorial is broken down into two parts. We will start by learning how to create a RESTful service, then further down, we will learn how to interact with it in a few different ways.</p><h3>Part 1 &#8211; Creating a RESTful API</h3><h3>Step 1: Setting up the Demo</h3><p>Firstly you need to download the <a
href="http://github.com/philsturgeon/codeigniter-restserver">codeigniter-restserver</a> code from GitHub and extract it and move the code to your server.</p><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/552_ci/github-restserver.png" border="0" /></div><p>When you open the folder, you will see an entire CodeIgniter install, which is there to power the demo. This allows people to have a play with the REST demo before integrating with your existing application.</p><p>Open up <em>&#8220;application/config/config.php&#8221;</em> and set the base_url to get links working. This base_url will be different for everyone and depends entirely on where you uploaded your files.</p><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/552_ci/set-base-url.png" border="0" /></div><h3>Step 2: The URLs</h3><p>With the files extracted and the base_url set, we are ready to load up our RESTful CodeIgniter installation, and have a look at the demo supplied with it. Browse the base URL, which by default is:</p><blockquote><p><strong>http://localhost/restserver</strong></p></blockquote><p>Here you will find a few example links to the <em>example_api</em> controller, which can be found at <em>&#8220;application/controllers/example_api.php&#8221;</em>. Let&#8217;s dissect the URL&#8217;s of these examples to see what is going on. The first URL is a very simple one.</p><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/552_ci/url-disect-1.png" border="0" /></div><p>This URL looks very much like any other CodeIgniter URL with a controller and a method, but you will notice in this diagram that the method is named a &#8220;Resource&#8221;. REST is all about Resources and they are essentially a noun within your application, which are interacted with (i.e added, deleted, edited, queried)  based on HTTP headers and URL query strings or HTTP arguments.</p><p>The default format for output is XML which is what we see in this basic example. The other links are slightly larger and demonstrate how to pass parameters and show how the output format can be modified in the URL:</p><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/552_ci/url-disect-2.png" border="0" /></div><p>Normally in CodeIgniter, you just pass in parameter values, but a REST controller accepts any number of parameters in any order. For this to work, we need to pass in the name of the parameter followed by the value in pairs.</p><p>At the end of the URL is the &#8220;format&#8221; parameter. This is a reserved parameter that will modify the output format of the requested data like so:</p><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/552_ci/output-examples.png" border="0" style="width:600px;" /></div><p>By giving both the API developer and the client application the choice of data formats to use, the API is opened up to a much wider audience and can be used with more programming languages and systems. These three are not the only formats supported, out of the box your REST API can use:</p><ul><li><strong>xml</strong> &#8211; almost any programming language can read XML</li><li><strong>json</strong> &#8211; useful for JavaScript and increasingly PHP apps.</li><li><strong>csv</strong> &#8211; open with spreadsheet programs</li><li><strong>html</strong> &#8211; a simple HTML table</li><li><strong>php</strong> &#8211; Representation of PHP code that can be eval()&#8217;ed</li><li><strong>serialize</strong> &#8211; Serialized data that can be unserialized in PHP</li></ul><p>While adding the format to the URL is not technically the most RESTful way to change formats, it allows for easy browser testing and lets developers without cURL perform simple GET requests on the API. The more RESTful way is to send a <em>Content-type</em> HTTP header to the REST controller using cURL, but that will be explained later.</p><h3>Step 3: The Code</h3><p>Now if you open up <em>application/controllers/example_api.php</em> you will immediatley spot a few differences from normal CodeIgniter controllers.</p><h4>REST_Controller</h4><p>In the MVC pattern, a controller is the central point of the logic. It is called when a user makes a request and then based on the logic in the controller it fetches data and outputs views. CodeIgniter contains its own logic for how a Controller should work, but as we are doing something different we need our own REST_Controller library to contain its own REST related logic. So instead of simply using:</p><pre name="code" class="php">
&lt;?php
class Example_api extends Controller {

}
</pre><p>&#8230;you will need to use:</p><pre name="code" class="php">
&lt;?php
require(APPPATH'.libraries/REST_Controller.php');

class Example_api extends REST_Controller {

}
</pre><h4>Working with Resources</h4><p>Now your empty controller is set up, next are the methods or &#8220;resources&#8221;. This is prossibly the most confusing part of the tutorial if you are used to how CodeIgniter works. Basically, you take the Resource and the HTTP verb and combine them to make a method name. So the two examples we looked at before had a Resource of <strong>user</strong> and <strong>users</strong>. Because both of these were loaded in the browser, we know it was using a GET request and so the two methods below are used:</p><pre name="code" class="php">
&lt;?php
require(APPPATH'.libraries/REST_Controller.php');

class Example_api extends REST_Controller {

    function user_get()
    {
		// respond with information about a user
    }

    function users_get()
    {
		// respond with information about several users
    }
}
</pre><p>This may seem a little strange, but it gives you the ability to use the same URL and respond to the request depending on the HTTP verb that has been used. If somebody tries to access your API in a way that is not allowed (in this example PUT or DELETE) it will simply respond with a 404. If you aren&#8217;t sure about HTTP verbs, let me explain.</p><h4>GET</h4><p>Used to fetch information about an existing resource. This is used by browsers when you enter a URL and hit go, or when you click on a link, so it perfect for fetching information on one of your REST resources (like user).</p><h4>POST</h4><p>Used to update an existing resource with information. Browsers use this to submit most types of forms on the internet, although some use GET as well by submitting the form action with a query string containing the field data.</p><h4>PUT</h4><p>Less commonly used and not supported by most browsers, PUT is used to create a new resource.</p><h4>DELETE</h4><p>Also not used by many browsers, this HTTP verb rather obviously is used to delete a resource.</p><p>If we put that into code and allow each verb on the resource <strong>user</strong> it would look like this:</p><pre name="code" class="php">
&lt;?php
require(APPPATH'.libraries/REST_Controller.php');

class Example_api extends REST_Controller {

    function user_get()
    {
		// respond with information about a user
    }

    function user_put()
    {
		// create a new user and respond with a status/errors
    }

    function user_post()
    {
		// update an existing user and respond with a status/errors
    }

    function user_delete()
    {
		// delete a user and respond with a status/errors
    }
}
</pre><h4>Accessing parameters and returning data</h4><p>So now the API has been given its structure by setting up the resources and defining a method for each HTTP verb we wish to support; we need parameters so we can use our CodeIgniter models and libraries. This is one of the major benefits of using CodeIgniter for our API, as we can use our existing models and libraries and not have to re-code them.</p><pre name="code" class="php">
&lt;?php
require(APPPATH'.libraries/REST_Controller.php');

class Example_api extends REST_Controller {

    function user_get()
    {
		$data = array('returned: '. $this->get('id'));
		$this->response($data);
    }

    function user_post()
    {
		$data = array('returned: '. $this->post('id'));
		$this->response($data);
    }

    function user_put()
    {
		$data = array('returned: '. $this->put('id'));
		$this->response($data;
    }

    function user_delete()
    {
		$data = array('returned: '. $this->delete('id'));
		$this->response($data);
    }
}
</pre><p>This example contains five new pieces of code:</p><h4>$this->get()</h4><p>Is used to return GET variables from either a query string like this index.php/example_api/user?id=1 or can be set in the more CodeIgniter&#8217;esque way with index.php/example_api/user/id/1.</p><h4>$this->post()</h4><p>Is an alias for $this->input->post() which is CodeIgniter&#8217;s method to access $_POST variables with XSS protection.</p><h4>$this->put()</h4><p>Reads in PUT arguments set in the HTTP headers or via cURL.</p><h4>$this->delete()</h4><p>You guessed it, this reads in DELETE arguments, also set in HTTP headers or via cURL.</p><h4>$this->response()</h4><p>Sends data to the browser in whichever data format has been requested, or defaults to XML. You can optionally pass a HTTP status code to show it has worked or failed. E.g if the ID provided was not in the database, you could use $this->response(array(&#8216;error&#8217; => &#8216;User not found.&#8217;), 404);</p><h3>Step 4: Working with your Models</h3><p>Until now, we have been working with an example API in a clean install. So the next step is to get a REST API running from your existing codebase.</p><div
class="tutorial_image"><img
src="http://nettuts.s3.cdn.plus.org/552_ci/restserver-important-files.png" border="0" /></div><p>Although the download comes with a full CodeIgniter installation for the demo and to allow API&#8217;s to be built from scratch, the only two files of importance are:</p><ol><li>application/config/rest.php</li><li>application/libraries/REST_Controller.php</li></ol><p>Drop those two files into your CodeIgniter application and create a new API controller.</p><pre name="code" class="php">
&lt;?php
require(APPPATH.'/libraries/REST_Controller.php');

class Api extends REST_Controller
{
	function user_get()
    {
        if(!$this->get('id'))
        {
        	$this->response(NULL, 400);
        }

        $user = $this->user_model->get( $this->get('id') );

        if($user)
        {
            $this->response($user, 200); // 200 being the HTTP response code
        }

        else
        {
            $this->response(NULL, 404);
        }
    }

    function user_post()
    {
        $result = $this->user_model->update( $this->post('id'), array(
        	'name' => $this->post('name'),
        	'email' => $this->post('email')
        ));

        if($result === FALSE)
        {
        	$this->response(array('status' => 'failed'));
        }

        else
        {
        	$this->response(array('status' => 'success'));
        }

    }

    function users_get()
    {
        $users = $this->user_model->get_all();

        if($users)
        {
            $this->response($users, 200);
        }

        else
        {
            $this->response(NULL, 404);
        }
    }
}
?>
</pre><p>This shows an example API with some generic model names. In the first method, we are picking up a ?id=XX and passing it to the model. If data is found we send it to the $this->response() function with a status 200. If nothing is found, return no body and a 404 to say nothing was found. You can imagine how this could be expanded to run all sorts of API activities for your web application.</p><h3>Step 5: Securing the API</h3><p>Now your API is built it needs securing so only users given access can interact with the API. To set the login type, usernames and passwords open up <em>&#8220;application/config/rest.php&#8221;</em> inside your codebase.</p><pre name="code" class="php">
/*
|--------------------------------------------------------------------------
| REST Login
|--------------------------------------------------------------------------
|
| Is login required and if so, which type of login?
|
|	'' = no login required, 'basic' = relatively secure login, 'digest' = secure login
|
*/
$config['rest_auth'] = 'basic';
</pre><h4>None</h4><p>Anyone can interact with any one of of your API controllers.</p><h4>Basic</h4><p>A relatively insecure login method which should only be used on internal/secure networks.</p><h4>Digest</h4><p>A much more secure login method which encrypts usernames and password. If you wish to have a protected API which anyone could get at, use digest.</p><pre name="code" class="php">
/*
|--------------------------------------------------------------------------
| REST Login usernames
|--------------------------------------------------------------------------
|
| Array of usernames and passwords for login
|
|	array('admin' => '1234')
|
*/
$config['rest_valid_logins'] = array('admin' => '1234');
</pre><p>Setting up the users is simple. Each login is an array item, with a key and a value. The key is the username and the value is the password. Add as many as you like to this array and dish them out to anyone who will be using the API.</p><h3>Part 2 &#8211; Interacting with RESTful Services</h2><p>Whether it is the API you have just built or a public service such as Twitter, you will want to be able to interact with it somehow. Seeing as RESTful services work with basic HTTP requests it is very easy to do this in a number of different ways.</p><h3>Different Methods to Interact with REST</h3><p>Each of these different interaction methods will be shown with the code placed directly in the Controller methods. This is purely so the demos are easier to read and would normally would be placed inside a model or a library for correct MVC separation.</p><h4>file_get_contents()</h4><p>Using the very simple PHP function file_get_contents(), you can perform a basic GET request. This is the most basic of all the methods but is worth mentioning for those &#8220;quick and dirty&#8221; moments.</p><pre name="code" class="php">
$user = json_decode(
	file_get_contents('http://example.com/index.php/api/user/id/1/format/json')
);

echo $user->name;
</pre><p>It&#8217;s worth noting that, while this method will not work using HTTP Digest authentication, if you are using HTTP Basic authentication you can use the following syntax to get data from your password protected RESTful API:</p><pre name="code" class="php">
$user = json_decode(
	file_get_contents('http://admin:1234@example.com/index.php/api/user/id/1/format/json')
);

echo $user->name;
</pre><p>There are a few problems with using this method: the only way to set extra HTTP headers is to set them manually using the PHP function <a
href="http://php.net/stream_context_create" target="_blank">stream_context_create()</a>, which can be very complicated for developers who are new to the internal workings of HTTP requests. Another disadvantage is that you only receive the body of the HTTP response in its raw format, which means you need to handle conversion from very single request.</p><h4>cURL</h4><p>cURL is the most flexible way to interact with a REST API as it was designed for exactly this sort of thing. You can set HTTP headers, HTTP parameters and plenty more. Here is an example of how to update a user with our example_api and cURL to make a POST request:</p><pre name="code" class="php">

    function native_curl($new_name, $new_email)
    {
	    $username = 'admin';
		$password = '1234';

		// Alternative JSON version
		// $url = 'http://twitter.com/statuses/update.json';
		// Set up and execute the curl process
		$curl_handle = curl_init();
		curl_setopt($curl_handle, CURLOPT_URL, 'http://localhost/restserver/index.php/example_api/user/id/1/format/json');
		curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
		curl_setopt($curl_handle, CURLOPT_POST, 1);
		curl_setopt($curl_handle, CURLOPT_POSTFIELDS, array(
			'name' => $new_name,
			'email' => $new_email
		));

		// Optional, delete this line if your API is open
		curl_setopt($curl_handle, CURLOPT_USERPWD, $username . ':' . $password);

		$buffer = curl_exec($curl_handle);
		curl_close($curl_handle);

		$result = json_decode($buffer);

		if(isset($result->status) &#038;&#038; $result->status == 'success')
		{
			echo 'User has been updated.';
		}

		else
		{
			echo 'Something has gone wrong';
		}
    }
</pre><p>Interacting with your API this way works fine, but there are two problems with this method:</p><ol><li>It uses an ugly confusing syntax &#8211; imagine creating several an application based on that.</li><li>cURL is not installed on all servers by default.</li></ol><p>To solve this ugly syntax, a <a
href="http://codeigniter.com/wiki/Curl_library/" target="_blank">cURL library</a> has been developed for CodeIgniter which simplifies things immensely.</p><p>The exact same request made with the cURL library would look like this:</p><pre name="code" class="php">
    function ci_curl($new_name, $new_email)
    {
	    $username = 'admin';
		$password = '1234';

		$this->load->library('curl');

		$this->curl->create('http://localhost/restserver/index.php/example_api/user/id/1/format/json');

		// Optional, delete this line if your API is open
		$this->curl->http_login($username, $password);

		$this->curl->post(array(
			'name' => $new_name,
			'email' => $new_email
		));

		$result = json_decode($this->curl->execute());

		if(isset($result->status) &#038;&#038; $result->status == 'success')
		{
			echo 'User has been updated.';
		}

		else
		{
			echo 'Something has gone wrong';
		}
    }
</pre><p>Much nicer to look at right? Well there is an even easier method to work with REST in your CodeIgniter applications that this.</p><h4>REST client library</h4><p>A <a
href="http://github.com/philsturgeon/codeigniter-restclient" target="_blank">REST client library</a> has been developed that sits on top of this cURL library which handles format conversion, HTTP logins and several other aspects of your REST API.</p><pre name="code" class="php">
    function rest_client_example($id)
    {
		$this->load->library('rest', array(
			'server' => 'http://localhost/restserver/index.php/example_api/',
			'http_user' => 'admin',
			'http_pass' => '1234',
			'http_auth' => 'basic' // or 'digest'
		));

        $user = $this->rest->get('user', array('id' => $id), 'json');

        echo $user->name;
    }
</pre><p>Here you can see we are making a GET request, sending id as a parameter and telling the library we want &#8216;json&#8217; as the content format. This handles the setting of Content-type for you, and converts the data into a PHP object for you. You can change this value to &#8216;xml&#8217;, &#8216;json&#8217;, &#8217;serialize&#8217;, &#8216;php&#8217;, &#8216;csv&#8217; or any custom MIME-type you like, for example:</p><pre name="code" class="php">
	$user = $this->rest->get('user', array('id' => $id), 'application/json');
</pre><p>As you have probably guessed as well as $this->rest->get(), the library also supports $this->rest->post(), $this->rest->put(), $this->rest->delete() to match all of your REST_Controller methods.</p><p>You will need to var_dump() results coming from the REST client library to make sure you are getting the right data format back. The conversion will somtimes be array and sometimes be an object, depending on how it is converted by PHP. If the returned MIME-type is not supported then it will simply return the format as plain-text.</p><h3>Talking to Twitter</h3><p>Using this REST library you can talk other RESTful services such as Twitter and Facebook. Here is a simple example of how you can get details for a specfic user based on their ID, using Twitter&#8217;s default format XML.</p><pre name="code" class="php">
        $this->load->library('rest', array('server' => 'http://twitter.com/'));

        $user = $this->rest->get('users/show', array('screen_name' => 'philsturgeon'));
</pre><pre name="code" class="php">
        $this->load->library('rest', array(
        	'server' => 'http://twitter.com/',
			'http_user' => 'username',
			'http_pass' => 'password',
			'http_auth' => 'basic'
        ));

        $user = $this->rest->post('statuses/update.json', array('status' => 'Using the REST client to do stuff'));
</pre><p>Looking at this, you will notice that interacting with the Twitter API is a bit different in a few ways.</p><ol><li>They support URL based format switching in the form of .json instead of /format/json. Some require an extension, some do not; so it&#8217;s best to always add them.</li><li>They mostly only support GET/POST, but are starting to add more DELETE methods</li><li>They don&#8217;t always have just a resource in their URL, for example: <em>users/search</em> is one REST method, but <em>lists</em> is another.</li></ol><p>Keep an eye out for these differences as they can catch you out. If you get stuck, simply echo $this->rest->debug() for a whole range of information on your REST request.</p><h3>Summary</h3><p>Combining what you now know about RESTful services, the CodeIgniter REST client library and the <a
href="http://apiwiki.twitter.com/Twitter-API-Documentation" target="_blank">Twitter API documentation</a> &#8211; or any other RESTful API documentation for that matter &#8211; you can create some very powerful applications that integrate with any custom or public web service using REST. You can extend your API by creating more REST_Controller&#8217;s and even make a modular API by using <a
href="http://code.google.com/p/matchbox/" target="_blank">Matchbox</a> or <a
href="http://codeigniter.com/forums/viewthread/121820/">Modular Separation</a> to create an api.php controller for each module to help keep your API as neatly organized as your application.</p><h3>Write a Plus Tutorial</h3><p><strong>Did you know that you can earn up to $600 for writing a PLUS tutorial and/or screencast for us? </strong>We&#8217;re looking for in depth and well-written tutorials on HTML, CSS, PHP, and JavaScript. If you&#8217;re of the ability, please contact Jeffrey at nettuts@tutsplus.com.</p><p>Please note that actual compensation will be dependent upon the quality of the final tutorial and screencast.</p><div
class="tutorial_image"><a
href="http://tutsplus.com/plus-program/net-plus/"><img
src="http://miscfiles.s3.amazonaws.com/banners/nettuts_728x90.jpg" alt="Write a PLUS tutorial" style="width:600px;" /></a></div><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/php/working-with-restful-services-in-codeigniter-2/feed/</wfw:commentRss> <slash:comments>33</slash:comments> </item> <item><title>Quick Tip: How to Use the New &#8220;Post-Thumbnail&#8221; Feature in WordPress 2.9</title><link>http://net.tutsplus.com/tutorials/wordpress/quick-tip-how-to-use-the-new-post-thumbnail-feature-in-wordpress-2-9/</link> <comments>http://net.tutsplus.com/tutorials/wordpress/quick-tip-how-to-use-the-new-post-thumbnail-feature-in-wordpress-2-9/#comments</comments> <pubDate>Thu, 04 Feb 2010 07:58:58 +0000</pubDate> <dc:creator>Jeffrey Way</dc:creator> <category><![CDATA[Screencasts]]></category> <category><![CDATA[Wordpress]]></category> <category><![CDATA[add_theme_support]]></category> <category><![CDATA[wordpress 2.9]]></category> <category><![CDATA[wordpress thumbnails]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9096</guid> <description><![CDATA[<img
src="http://nettuts.s3.amazonaws.com/563_wpThumbnails/200x200.png" alt="Quick Tip: How to Use the New "Post-Thumbnail" Feature in WordPress 2.9" />]]></description> <content:encoded><![CDATA[<p> Up until the release of WordPress 2.9, setting up &#8220;post-image&#8221; support for your blog was a bit more tedious a task than it really needed to be. Luckily, that&#8217;s no longer an issue. I&#8217;ll show you how to get setup in this four minute video quick tip.</p><p><span
id="more-9096"></span></p><div
class="tutorial_image"> <object
classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='600' height='369'><param
name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param
name='flashvars' value='i=44298' /><param
name='allowFullScreen' value='true' /><embed
src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=44298' allowFullScreen='true' width='600' height='369' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></div><h3>Step 1. Edit your Functions.php Page</h3><pre name="code" class="php">
// Enable support for post-thumbnails

add_theme_support('post-thumbnails');

// If we want to ensure that we only call this function if
// the user is working with WP 2.9 or higher,
// let's instead make sure that the function exists first

if ( function_exists('add_theme_support') ) {
	add_theme_support('post-thumbnails');
}
</pre><h3>Step 2. Insert the Image Tag into your Loop</h3><p>Within the &#8220;if have_posts()&#8221; loop, simply place this piece of code anywhere you like. At that point, WordPress will insert an image tag onto the page accordingly. Please note that you&#8217;ll have access to a &#8220;wp-post-image&#8221; class that you may then work with to format/style the image.</p><pre name="code" class="php">
&lt;?php the_post_thumbnail(); ?>
</pre><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/wordpress/quick-tip-how-to-use-the-new-post-thumbnail-feature-in-wordpress-2-9/feed/</wfw:commentRss> <slash:comments>44</slash:comments> </item> <item><title>An In-Depth Overview of File Operations in PHP: New Plus Tutorial</title><link>http://net.tutsplus.com/tutorials/php/an-in-depth-overview-of-file-operations-in-php-new-plus-tutorial/</link> <comments>http://net.tutsplus.com/tutorials/php/an-in-depth-overview-of-file-operations-in-php-new-plus-tutorial/#comments</comments> <pubDate>Wed, 03 Feb 2010 20:42:21 +0000</pubDate> <dc:creator>Burak Guzel</dc:creator> <category><![CDATA[PHP]]></category> <category><![CDATA[Plus]]></category> <category><![CDATA[file operations]]></category> <category><![CDATA[php file]]></category> <category><![CDATA[php file operations]]></category> <category><![CDATA[php screencasts]]></category> <category><![CDATA[php video tutorial]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9106</guid> <description><![CDATA[<img
src="http://nettutsplus.s3.amazonaws.com/53_fileOperations/200x200.png" alt="An In Depth Overview of File Operations in PHP" />]]></description> <content:encoded><![CDATA[<p> In this week&#8217;s Plus tutorial, we will learn how to work with file operations using PHP. This is one of the most fundamental subjects of server side programming in general. Files are used in web applications of all sizes. So let&#8217;s learn how to read, write, create, move, copy, delete files and more. <a
href="http://net.tutsplus.com/about/join-plus/">Help give back to Nettuts+, and become a Plus member!</a></p><p><span
id="more-9106"></span></p><h3>Why You Should Join Plus</h3><div
class="tutorial_image"> <object
classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='600' height='369'><param
name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param
name='flashvars' value='i=44355' /><param
name='allowFullScreen' value='true' /><embed
src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=44355' allowFullScreen='true' width='600' height='369' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object></div><div
class="tutorial_image"><img
src="http://miscfiles.s3.amazonaws.com/banners/nettuts_468x60.jpg" border=0 alt="NETTUTS+ Screencasts and Bonus Tutorials" width=468 height=60></div><p> For those unfamiliar, the family of TUTS sites runs a premium membership service called <a
href="http://www.tutsplus.com">&#8220;TUTSPLUS&#8221;</a>. For $9 per month, you gain access to exclusive premium tutorials, screencasts, and freebies from <a
href="http://net.tutsplus.com">Nettuts+</a>, <a
href="psd.tutsplus.com">Psdtuts+</a>, <a
href="ae.tutsplus.com">Aetuts+</a>, <a
href="audio.tutsplus.com">Audiotuts+</a>, and <a
href="vector.tutsplus.com">Vectortuts+!</a> For the price of a pizza, you&#8217;ll learn from some of the best minds in the business. <a
href="http://net.tutsplus.com/about/join-plus/">Become a Plus member.</a></p><ul
class="webroundup"><li>Subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for more daily web development tuts and articles.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/php/an-in-depth-overview-of-file-operations-in-php-new-plus-tutorial/feed/</wfw:commentRss> <slash:comments>11</slash:comments> </item> <item><title>How to Test your JavaScript Code with QUnit</title><link>http://net.tutsplus.com/tutorials/javascript-ajax/how-to-test-your-javascript-code-with-qunit/</link> <comments>http://net.tutsplus.com/tutorials/javascript-ajax/how-to-test-your-javascript-code-with-qunit/#comments</comments> <pubDate>Wed, 03 Feb 2010 16:10:46 +0000</pubDate> <dc:creator>Gavin Huang</dc:creator> <category><![CDATA[JavaScript & AJAX]]></category> <category><![CDATA[javascript testing]]></category> <category><![CDATA[jquery team]]></category> <category><![CDATA[qunit]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9077</guid> <description><![CDATA[<img
src="http://nettuts.s3.cdn.plus.org/562_qunit/qunit.png" alt="How to Test your JavaScript Code with QUnit">]]></description> <content:encoded><![CDATA[<p><a
href="http://docs.jquery.com/QUnit">QUnit</a>, developed by the jQuery team, is a great framework for unit testing your JavaScript. In this tutorial, I&#8217;ll introduce what QUnit specifically is, and why you should care about rigorously testing your code.</p><p><span
id="more-9077"></span></p><h3>Tutorial Details</h3><ul><li><b>Language</b>: JavaScript</li><li><b>Difficulty:</b> Intermediate</li><li><b>Estimated Completion Time:</b> 30 minutes</li><li><strong>Required File: </strong> <a
href="http://github.com/jquery/qunit/raw/master/qunit/qunit.js">QUnit JS</a></li></ul><h3>What is QUnit</h3><p><a
href="http://docs.jquery.com/QUnit">QUnit</a> is a powerful JavaScript unit testing framework that helps you to debug code. It&#8217;s written by members of the <a
href="http://jquery.com/">jQuery</a> team, and is the official test suite for jQuery. But QUnit is general enough to test any regular JavaScript code, and it&#8217;s even able to test server-side JavaScript via some JavaScript engine like Rhino or V8.</p><p>If you&#8217;re unfamiliar with the idea of &#8220;unit testing&#8221;, don&#8217;t worry. It&#8217;s not too difficult to understand:</p><blockquote><p>In computer programming, unit testing is a software verification and validation method in which a programmer tests if individual units of source code are fit for use. A unit is the smallest testable part of an application. In procedural programming a unit may be an individual function or procedure.</p></blockquote><p>This is quoted from Wikipedia. Simply put, you write tests for each functionality of your code, and if all of these tests are passed, you can be sure that the code will be bug-free (mostly, depends on how thorough your tests are).</p><h3>Why You Should Test Your Code</h3><p><strong>If you haven&#8217;t written any unit tests before, you probably just apply your code to a website directly, click for a while to see if any problem occurs, and try to fix it as you spot one. There are many problems with this method.</strong></p><p> First, it&#8217;s very tedious. Clicking actually is not an easy job, because you have to make sure everything is clicked and it&#8217;s very likely you&#8217;ll miss one thing or two. Second, everything you did for testing is not reusable, which means it&#8217;s not easy to find regressions. What is a regression? Imagine that you wrote some code and tested it, fixed all the bugs you found, and published it. Then, a user sends some feedback about new bugs, and requests some new features. You go back to the code, fix these new bugs and add these new features. What might happen next is that some of the old bugs come up again, which are called &#8220;regressions.&#8221; See, now you have to do the clicking again, and chances are you won&#8217;t find these old bugs again; even if you do, it&#8217;ll take a while before you figure out that the problem is caused by regressions. With unit testing, you write tests to find bugs, and once the code is modified, you filter it through the tests again. If a regression appears, some tests will definitely be failed, and you can easily spot them, knowing which part of the code contains the bug. Since you know what you have just modified, it can easily be fixed.</p><p>Another advantage of unit testing is especially for web development: it eases the testing of cross-browser compatibility. Just run your tests on different browsers, and if a problem occurs on one browser, you fix it and run these tests again, making sure it doesn&#8217;t introduce regression on other browsers. You can be sure that all of the target browsers are supported, once they all pass the tests.</p><p>I&#8217;d like to mention one of John Resig&#8217;s projects: <a
href="http://testswarm.com/">TestSwarm</a>. It takes JavaScript unit testing to a new level, by making it distributed. It&#8217;s a website that contains many tests, anyone can go there, run some of the tests, then return the result back to server. In this way, code can be tested on different browsers and even different platforms really quickly.</p><h3>How to Write Unit Tests with QUnit</h3><p>So how do you write unit tests with QUnit exactly? First, you need to set up a testing environment:</p><pre name="code" class="html">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
	&lt;title&gt;QUnit Test Suite&lt;/title&gt;
	&lt;link rel=&quot;stylesheet&quot; href=&quot;http://github.com/jquery/qunit/raw/master/qunit/qunit.css&quot; type=&quot;text/css&quot; media=&quot;screen&quot;&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;http://github.com/jquery/qunit/raw/master/qunit/qunit.js&quot;&gt;&lt;/script&gt;
	&lt;!-- Your project file goes here --&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;myProject.js&quot;&gt;&lt;/script&gt;
	&lt;!-- Your tests file goes here --&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;myTests.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
	&lt;h1 id=&quot;qunit-header&quot;&gt;QUnit Test Suite&lt;/h1&gt;
	&lt;h2 id=&quot;qunit-banner&quot;&gt;&lt;/h2&gt;
	&lt;div id=&quot;qunit-testrunner-toolbar&quot;&gt;&lt;/div&gt;
	&lt;h2 id=&quot;qunit-userAgent&quot;&gt;&lt;/h2&gt;
	&lt;ol id=&quot;qunit-tests&quot;&gt;&lt;/ol&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre><p>As you can see, a <a
href="http://github.com/jquery/qunit/raw/master/qunit/qunit.js">hosted version of QUnit framework</a> is used here.</p><p>The code that is going to be tested should be put into myProject.js, and your tests should be inserted into myTests.js. To run these tests, simply open this HTML file in a browser. Now it&#8217;s time to write some tests.</p><p>The building blocks of unit tests are assertions.</p><blockquote><p>An assertion is a statement that predicts the returning result of your code. If the prediction is false, the assertion has failed, and you know that something has gone wrong.</p></blockquote><p>To run assertions, you should put them into a test case:</p><pre name="code" class="js">
// Let's test this function
function isEven(val) {
	return val % 2 === 0;
}

test('isEven()', function() {
	ok(isEven(0), 'Zero is an even number');
	ok(isEven(2), 'So is two');
	ok(isEven(-4), 'So is negative four');
	ok(!isEven(1), 'One is not an even number');
	ok(!isEven(-7), 'Neither is negative seven');
})
</pre><p>Here we defined a function, isEven, which detects whether a number is even, and we want to test this function to make sure it doesn&#8217;t return wrong answers.</p><p>We first call test(), which constructs a test case; the first parameter is a string that will be displayed in the result, and the second parameter is a callback function that contains our assertions. This callback function will get called once QUnit is run.</p><p>We wrote five assertions, all of which are boolean. A boolean assertion expects its first parameter to be true. The second parameter is also a message that will be displayed in the result.</p><p>Here is what you get, once you run the test:</p><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/iseven_test.png" alt="a test for isEven()"></div><p>Since all these assertions have successfully passed, we can be pretty sure that<em> isEven()</em> will work as expected.</p><p>Let&#8217;s see what happens if an assertion has failed.</p><pre name="code" class="js">
// Let's test this function
function isEven(val) {
	return val % 2 === 0;
}

test('isEven()', function() {
	ok(isEven(0), 'Zero is an even number');
	ok(isEven(2), 'So is two');
	ok(isEven(-4), 'So is negative four');
	ok(!isEven(1), 'One is not an even number');
	ok(!isEven(-7), 'Neither does negative seven');

	// Fails
	ok(isEven(3), 'Three is an even number');
})
</pre><p>Here is the result:</p><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/iseven_test_fail.png" alt="a test contains failed assertion for isEven()"></div><p>The assertion has failed because we deliberately wrote it wrong, but in your own project, if the test doesn&#8217;t pass, and all assertion are correct, you know a bug has been found.</p><h3>More Assertions</h3><p>ok() is not the only assertion that QUnit provides. There are other kinds of assertions that are useful when testing your project:</p><h3>Comparison Assertion</h3><p>The comparison assertion, equals(), expects its first parameter (which is the actual value) is equal to its second parameter (which is the expected value). It&#8217;s similar to ok(), but outputs both actual and expected values, making debugging much easier. Like ok(), it takes an optional third parameter as a message to be displayed.</p><p>So instead of:</p><pre name="code" class="js">
test('assertions', function() {
	ok( 1 == 1, 'one equals one');
})
</pre><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/boolean_assertion.png" alt="a boolean assertion"></div><p>You should write:</p><pre name="code" class="js">
test('assertions', function() {
	equals( 1, 1, 'one equals one');
})
</pre><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/comparison_assertion.png" alt="a comparison assertion"></div><p>Notice the last &#8220;1&#8243;, which is the comparing value.</p><p>And if the values are not equal:</p><pre name="code" class="js">
test('assertions', function() {
	equals( 2, 1, 'one equals one');
})
</pre><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/comparison_assertion_fail.png" alt="a failed comparison assertion"></div><p>It gives a lot more information, making life a lot easier.</p><p>The comparison assertion uses &#8220;==&#8221; to compare its parameters, so it doesn&#8217;t handle array or object comparison:</p><pre name="code" class="js">
test('test', function() {
	equals( {}, {}, 'fails, these are different objects');
	equals( {a: 1}, {a: 1} , 'fails');
	equals( [], [], 'fails, there are different arrays');
	equals( [1], [1], 'fails');
})
</pre><p>In order to test this kind of equality, QUnit provides another kind assertion: <strong>identical assertion</strong>.</p><h3>Identical Assertion</h3><p>Identical assertion, same(), expects the same parameters as equals(), but it&#8217;s a deep recursive comparison assertion that works not only on primitive types, but also arrays and objects. Assertions, in the previous example, will all pass if you change them to identical assertions:</p><pre name="code" class="js">
test('test', function() {
	same( {}, {}, 'passes, objects have the same content');
	same( {a: 1}, {a: 1} , 'passes');
	same( [], [], 'passes, arrays have the same content');
	same( [1], [1], 'passes');
})
</pre><p>Notice that same() uses &#8216;===&#8217; to do comparison when possible, so it&#8217;ll come in handy when comparing special values:</p><pre name="code" class="js">
test('test', function() {
	equals( 0, false, 'true');
	same( 0, false, 'false');
	equals( null, undefined, 'true');
	same( null, undefined, 'false');
})
</pre><h3>Structure Your Assertions</h3><p>Putting all assertions in a single test case is a really bad idea, because it&#8217;s very hard to maintain, and doesn&#8217;t return a clean result. What you should do is to structure them, put them into different test cases, each aiming for a single functionality.</p><p>You can even organize test cases into different modules by calling the module function:</p><pre name="code" class="js">
module('Module A');
test('a test', function() {});
test('an another test', function() {});

module('Module B');
test('a test', function() {});
test('an another test', function() {});
</pre><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/structure_assertions.png" alt="structure assertions"></div><h3>Asynchronous Test</h3><p>In previous examples, all assertions are called synchronously, which means they run one after another. In the real world, there are also many asynchronous functions, such as ajax calls or functions called by setTimeout() and setInterval(). How can we test these kinds of functions? QUnit provides a special kind of test case called &#8220;asynchronous test,&#8221; which is dedicated to asynchronous testing:</p><p>Let&#8217;s first try to write it in a regular way:</p><pre name="code" class="js">
test('asynchronous test', function() {
	setTimeout(function() {
		ok(true);
	}, 100)
})
</pre><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/async_test_wrong.png" alt="an incorrent example of asychronous test"></div><p>See? It&#8217;s as if we didn&#8217;t write any assertion. This is because the assertion ran asynchronously, by the time it got called, the test case had already finished.</p><p>Here is the correct version:</p><pre name="code" class="js">
test('asynchronous test', function() {
	// Pause the test first
	stop();

	setTimeout(function() {
		ok(true);

		// After the assertion has been called,
		// continue the test
		start();
	}, 100)
})
</pre><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/async_test.png" alt="a correct example of asychronous test"></div><p>Here, we use stop() to pause the test case, and after the assertion has been called, we use start() to continue.</p><p>Calling stop() immediately after calling test() is quite common; so QUnit provides a shortcut: asyncTest(). You can rewrite the previous example like this:</p><pre name="code" class="js">
asyncTest('asynchronous test', function() {
	// The test is automatically paused

	setTimeout(function() {
		ok(true);

		// After the assertion has been called,
		// continue the test
		start();
	}, 100)
})
</pre><p>There is one thing to watch out for: setTimeout() will always call its callback function, but what if it&#8217;s a custom function (e.g, an ajax call). How can you be sure the callback function will be called? And if the callback is not called, start() won&#8217;t be called, and the whole unit testing will hang:</p><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/562_qunit/unit_testing_hangs.png" alt="unit testing hangs"></div><p>So here is what you do:</p><pre name="code" class="js">
// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

test('asynchronous test', function() {
	// Pause the test, and fail it if start() isn't called after one second
	stop(1000);

	ajax(function() {
		// ...asynchronous assertions

		start();
	})
})
</pre><p>You pass a timeout to stop(), which tells QUnit, &#8220;if start() isn&#8217;t called after that timeout, you should fail this test.&#8221; You can be sure that the whole testing won&#8217;t hang and you&#8217;ll be notified if something goes wrong.</p><p>How about multiple asynchronous functions? Where do you put the start()? You put it in setTimeout():</p><pre name="code" class="js">
// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

test('asynchronous test', function() {
	// Pause the test
	stop();

	ajax(function() {
		// ...asynchronous assertions
	})

	ajax(function() {
		// ...asynchronous assertions
	})

	setTimeout(function() {
		start();
	}, 2000);
})
</pre><p>The timeout should be reasonably long enough to allow both callbacks to be called before the test continues. But what if one of the callback isn&#8217;t called? How can you know that? This is where expect() comes in:</p><pre name="code" class="js">
// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

test('asynchronous test', function() {
	// Pause the test
	stop();

	// Tell QUnit that you expect three assertions to run
	expect(3);

	ajax(function() {
		ok(true);
	})

	ajax(function() {
		ok(true);
		ok(true);
	})

	setTimeout(function() {
		start();
	}, 2000);
})
</pre><p>You pass in a number to expect() to tell QUnit that you expect X many assertions to run, if one of the assertion isn&#8217;t called, the number won&#8217;t match, and you&#8217;ll be notified that something went wrong.</p><p>There is also a shortcut for expect(): you just pass the number as the second parameter to test() or asyncTest():</p><pre name="code" class="js">
// A custom function
function ajax(successCallback) {
	$.ajax({
		url: 'server.php',
		success: successCallback
	});
}

// Tell QUnit that you expect three assertion to run
test('asynchronous test', 3, function() {
	// Pause the test
	stop();

	ajax(function() {
		ok(true);
	})

	ajax(function() {
		ok(true);
		ok(true);
	})

	setTimeout(function() {
		start();
	}, 2000);
})
</pre><h3>Conclusion</h3><p>That&#8217;s all you need to know to get started witih QUnit. Unit testing is a great method to test your code before publishing it. If you haven&#8217;t written any unit tests before, it&#8217;s time to get started! Thanks for reading!</p><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/tutorials/javascript-ajax/how-to-test-your-javascript-code-with-qunit/feed/</wfw:commentRss> <slash:comments>32</slash:comments> </item> <item><title>Facebook Hopes to Revolutionize PHP with &#8220;Hip Hop&#8221;</title><link>http://net.tutsplus.com/articles/news/facebook-hopes-to-revolutionize-php-with-hip-hop/</link> <comments>http://net.tutsplus.com/articles/news/facebook-hopes-to-revolutionize-php-with-hip-hop/#comments</comments> <pubDate>Wed, 03 Feb 2010 06:45:27 +0000</pubDate> <dc:creator>Jeffrey Way</dc:creator> <category><![CDATA[News]]></category> <category><![CDATA[facebook devs hip hop]]></category> <category><![CDATA[facebook hip hop]]></category> <category><![CDATA[hip hop]]></category> <category><![CDATA[hip hop for php]]></category> <category><![CDATA[hip hop php]]></category><guid
isPermaLink="false">http://net.tutsplus.com/?p=9055</guid> <description><![CDATA[<img
src="http://nettuts.s3.cdn.plus.org/561_hipHop/200x200.jpg" alt="Facebook Hopes to Revolutionize PHP with "Hip Hop"" />]]></description> <content:encoded><![CDATA[<p> Little <a
href="http://developers.facebook.com/news.php?tab=blog">did we know</a> that, for the last six months, Facebook has made use of a custom compiler for PHP that they refer to as &#8220;Hip Hop.&#8221; Essentially, it takes your PHP source code, and converts it into C++, and is then compiled with G++. As a result, they&#8217;ve managed to reduce their CPU usage by 50%. This project has apparently been in development for the last two years, but has only today been <a
href="http://developers.facebook.com/hiphop-php/">released to the community</a>.</p><p><span
id="more-9055"></span></p><blockquote><p> &#8220;HipHop for PHP isn&#8217;t technically a compiler itself. Rather it is a source code transformer. HipHop programmatically transforms your PHP source code into highly optimized C++ and then uses g++ to compile it. HipHop executes the source code in a semantically equivalent manner and sacrifices some rarely used features — such as eval() — in exchange for improved performance. HipHop includes a code transformer, a reimplementation of PHP&#8217;s runtime system, and a rewrite of many common PHP Extensions to take advantage of these performance optimizations.&#8221;</p></blockquote><h3>The Announcement</h3><div
class="tutorial_image"> <object
classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="600" height="483" id="utv10325" name="utv_n_386990"><param
name="flashvars" value="autoplay=false" /><param
name="allowfullscreen" value="true" /><param
name="allowscriptaccess" value="always" /><param
name="src" value="http://www.ustream.tv/flash/video/4409735" /><embed
flashvars="autoplay=false" width="600" height="483" allowfullscreen="true" allowscriptaccess="always" id="utv10325" name="utv_n_386990" src="http://www.ustream.tv/flash/video/4409735" type="application/x-shockwave-flash" /></object></div><blockquote><p> &#8220;Scaling Facebook is particularly challenging because almost every page view is a logged-in user with a customized experience. When you view your home page we need to look up all of your friends, query their most relevant updates (from a custom service we&#8217;ve built called Multifeed), filter the results based on your privacy settings, then fill out the stories with comments, photos, likes, and all the rich data that people love about Facebook. All of this in just under a second. HipHop allows us to write the logic that does the final page assembly in PHP and iterate it quickly while relying on custom back-end services in C++, Erlang, Java, or Python to service the News Feed, search, Chat, and other core parts of the site.&#8221;</p></blockquote><h3>The Problems Facebook Faced with PHP</h3><ul><li>Can&#8217;t reuse PHP logic in other systems</li><li>Extensions are harder to write for PHP developers</li><li>High CPU usage; can&#8217;t be as efficient as something like C++</li><li>Fully impractical to completely rewrite Facebook with a new language</li></ul><h3>How They Improved It</h3><ul><li>It&#8217;s a source code transformer</li><li>Transforms PHP into optimized C++, then compiled with G++</li><li>Has been in development for over two years.</li><li>If you&#8217;ve used Facebook within the last six months, you&#8217;ve experience Hip Hop</li><li>Facebook team have recorded a 50% decrease in CPU usage.</li><li>They&#8217;ll have dedicated evangelists to help train/familiarize the community with Hip Hop</li><li>If you&#8217;re on a shared host, using Apache, you&#8217;ll most likely want to continue using standard PHP</li><h3>Where Can We Start Playing with It?</h3><p>Hip Hop is available now, and is hosted on Github. <a
href="http://developers.facebook.com/hiphop-php/">You can download it here</a>.</p><div
class="tutorial_image"> <img
src="http://nettuts.s3.cdn.plus.org/561_hipHop/graph.png" alt="Hip Hop Process Graph" style="width: 600px;" /></div><ul
class="webroundup"><li>Follow us on <a
href="http://www.twitter.com/nettuts">Twitter</a>, or subscribe to the <a
href="http://feeds.feedburner.com/nettuts" title="Nettuts+ RSS Feed">Nettuts+ RSS Feed</a> for the best web development tutorials on the web.</li></ul> ]]></content:encoded> <wfw:commentRss>http://net.tutsplus.com/articles/news/facebook-hopes-to-revolutionize-php-with-hip-hop/feed/</wfw:commentRss> <slash:comments>54</slash:comments> </item> </channel> </rss>
<!-- This site's performance optimized by W3 Total Cache. Dramatically improve the speed and reliability of your blog!

Learn more about our WordPress Plugins: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached
Page Caching using apc
Database Caching 24/26 queries in 0.110 seconds using memcached
Content Delivery Network via net.tutsplus.cdn.plus.org

Served from: 68.169.41.217.static.vps.net @ 2010-02-10 15:25:09 -->