<?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>blog.rohanlatimer.com.au</title>
	<atom:link href="http://rohanlatimer.com.au/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://rohanlatimer.com.au/blog</link>
	<description>melbourne freelance web developer</description>
	<lastBuildDate>Wed, 16 May 2012 12:49:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Building a CMS with CodeIgniter: Part 4 File Uploading</title>
		<link>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-4-file-uploading/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-4-file-uploading/#comments</comments>
		<pubDate>Wed, 16 May 2012 12:48:32 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodeIgnitor]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=158</guid>
		<description><![CDATA[so i&#8217;m cheating a bit here because i already have a file upload script i prepared earlier. this script allows the upload of an image to a directory. no extra fancy features. there are plenty of upload plugins out there &#8230; <a href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-4-file-uploading/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>so i&#8217;m cheating a bit here because i already have a file upload script i prepared earlier. this script allows the upload of an image to a directory. no extra fancy features. there are plenty of upload plugins out there but this is about as basic as you get. the script was orginally from the CI website <a href="http://codeigniter.com/user_guide/libraries/file_uploading.html" title="code igniter file uploading" target="_blank">here</a> although i have modified it a bit.</p>
<p>1. create a controller for handling uploads called upload. in this controller, place the following code:</p>
<pre>
&lt;?php

class Upload extends CI_Controller {

	function do_upload()
	{
		$config[&#039;upload_path&#039;] = FCPATH . &#039;uploads/&#039;;
		$config[&#039;allowed_types&#039;] = &#039;gif|jpg|png&#039;;
		$config[&#039;max_size&#039;]	= &#039;100&#039;;
		$config[&#039;max_width&#039;]  = &#039;1024&#039;;
		$config[&#039;max_height&#039;]  = &#039;768&#039;;

		$this-&gt;load-&gt;library(&#039;upload&#039;, $config);
		$this-&gt;upload-&gt;initialize($config);

		$this-&gt;output-&gt;set_output( base_url() . &#039;uploads/&#039; );

		if ( ! $this-&gt;upload-&gt;do_upload())
		{
			$error = array(&#039;error&#039; =&gt; $this-&gt;upload-&gt;display_errors());

			$this-&gt;load-&gt;view(&#039;v_upload_fail&#039;, $error);
		}
		else
		{
			$data = array(&#039;upload_data&#039; =&gt; $this-&gt;upload-&gt;data());

			$this-&gt;load-&gt;view(&#039;v_upload_success&#039;, $data);
		}
	}
}
?&gt;
</pre>
<p>2. create the view for upload fail and success.<br />
fail:</p>
<pre>
&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;Upload Failed&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;

		&lt;?php echo $error;?&gt;

	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>success:</p>
<pre>
&lt;html&gt;
	&lt;head&gt;
		&lt;title&gt;Upload Success&lt;/title&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;h3&gt;Your file was successfully uploaded!&lt;/h3&gt;

		&lt;ul&gt;
			&lt;?php foreach ($upload_data as $item =&gt; $value):?&gt;
			&lt;li&gt;&lt;?php echo $item;?&gt;: &lt;?php echo $value;?&gt;&lt;/li&gt;
			&lt;?php endforeach; ?&gt;
		&lt;/ul&gt;

		&lt;p&gt;&lt;?php echo anchor(&#039;welcome&#039;, &#039;Upload Another File!&#039;); ?&gt;&lt;/p&gt;

	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>4. now you need to create the uploads directory in the web server root and give it the correct permissions.</p>
<p>5. throw this code in the welcome view and you&#8217;re good to go.</p>
<pre>
&lt;?php
	echo form_open_multipart(&#039;upload/do_upload&#039;);
	echo form_input( array( &#039;type&#039; =&gt; &#039;file&#039;, &#039;name&#039; =&gt; &#039;userfile&#039;, &#039;size&#039; =&gt; &#039;20&#039; ) );
	echo form_submit( &#039;submit&#039;, &#039;Upload&#039; );
	echo form_close();
?&gt;
</pre>
<p>well that&#8217;s two parts in one night! phew i&#8217;m done for now. next part i&#8217;ll setup a basic database to handle creating pages and get into dynamic url routing.</p>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-4-file-uploading/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-4-file-uploading/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-4-file-uploading/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a CMS with CodeIgniter: Part 3 Basic text input</title>
		<link>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-3-basic-text-input/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-3-basic-text-input/#comments</comments>
		<pubDate>Wed, 16 May 2012 11:34:01 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodeIgnitor]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=143</guid>
		<description><![CDATA[so the point of this post is to first show how to make form input controls with Code Igniter, then to plug in a basic wysiwyg editor. for form inputs, just check this official code igniter page now for a &#8230; <a href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-3-basic-text-input/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>so the point of this post is to first show how to make form input controls with Code Igniter, then to plug in a basic wysiwyg editor.</p>
<p>for form inputs, just check this official <a href="http://codeigniter.com/user_guide/helpers/form_helper.html" title="code igniter form helper" target="_blank">code igniter page </a></p>
<p>now for a WYSIWYG editor, i&#8217;ll use a plug-in as these have been around for a while and its much quicker than making my own. tinymce is my weapon of choice. after a couple of hours coding in front of the telly i&#8217;ve got a working verson. note that i&#8217;ve decided to use the jquery version as it&#8217;s highly likely i&#8217;ll use jquery at some stage in this CMS and that means the file size will be a little smaller.</p>
<p>1. download tinymce from <a href="http://www.tinymce.com/download/download.php" title="tinymce download" target="_blank">here</a> and put it in your web directory under &#8216;js&#8217; for example.</p>
<p>2. download jquery from <a href="http://jquery.com/" title="jquery download" target="_blank">here</a>. add it into your directy. or you can link directly to the web version at google or whatever.</p>
<p>3. in the welcome view (remember, you are now logged in), add the following code to head section. this firstly includes the js files including the base url from CI. next some jquery targets textareas called &#8216;tinymce&#8217; and converts them to the wysiwyg editors. i&#8217;ve used the simple editor and changed the formatting so that css classes are used instead of html tags for bold, italic, underline and strikethrough. </p>
<pre>
&lt;script src=&quot;&lt;?=base_url()?&gt;js/jquery-1.7.2.min.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;&lt;?=base_url()?&gt;js/tiny_mce/jquery.tinymce.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
	$(document).ready(function(){
		$(&#039;textarea.tinymce&#039;).tinymce({
			// Location of TinyMCE script
			script_url : &#039;&lt;?=base_url()?&gt;js/tiny_mce/tiny_mce.js&#039;,
			theme : &quot;simple&quot;,
			formats : {
				bold : {inline : &#039;span&#039;, &#039;classes&#039; : &#039;bold&#039;},
				italic : {inline : &#039;span&#039;, &#039;classes&#039; : &#039;italic&#039;},
				underline : {inline : &#039;span&#039;, &#039;classes&#039; : &#039;underline&#039;, exact : true},
				strikethrough : {inline : &#039;span&#039;, &#039;classes&#039; : &#039;strikethrough&#039;, exact : true}
			}
		});
	});
&lt;/script&gt;
</pre>
<p>4. put the following php in the body part of the welcome view. this just creates a simple form with a textarea and submit button. there is also the logout button from the last part.</p>
<pre>
&lt;?php
	echo form_open(&#039;wysiwyg&#039;);
	echo form_textarea(array( &#039;name&#039; =&gt; &#039;content&#039;, &#039;class&#039; =&gt; &#039;tinymce&#039; ));
	echo form_submit(&#039;submit&#039;, &#039;Submit&#039;);
	echo form_close();
	echo anchor(&#039;logout&#039;, &#039;Logout&#039;, array(&#039;class&#039; =&gt; &#039;logout&#039;) );
?&gt;
</pre>
<p>5. now you need to make the wysiwyg controller. use the following code. the important part here is storing the contents of the text area in the data variable so you can pass it to the view. ideally i&#8217;ll store this in a database, but i need a database first!</p>
<pre>
&lt;?php if ( ! defined(&#039;BASEPATH&#039;)) exit(&#039;No direct script access allowed&#039;);

class WYSIWYG extends CI_Controller {

	public function __construct()
	{
		parent::__construct();
		$this-&gt;output-&gt;set_header(&quot;Cache-Control: no-store, no-cache, must-revalidate&quot;);

		$this-&gt;load-&gt;library(&#039;authenticate&#039;);
		$this-&gt;authenticate-&gt;checkLoggedIn();
	}

	public function index()
	{
		// store data in db here via model.

		// for now just spit it out to the page
		$data[&#039;content&#039;] = $this-&gt;input-&gt;post(&#039;content&#039;);
		$this-&gt;load-&gt;view(&#039;v_wysiwyg&#039;, $data);
	}
}
</pre>
<p>6. now for the view. here&#8217;s the code</p>
<pre>
&lt;html lang=&quot;en&quot;&gt;
	&lt;head&gt;
		&lt;meta charset=&quot;utf-8&quot;&gt;
		&lt;title&gt;WYSIWYG demo&lt;/title&gt;
	&lt;/head&gt;

	&lt;body&gt;
		&lt;h1&gt;WYSIWYG demo&lt;/h1&gt;
		&lt;?php
			echo $content;
		?&gt;

	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>that&#8217;s it! the wysiwyg is now passing the html typed by a user into a controller and then to a view. this is a very basic CMS! (without any db storage!)</p>
<p>next up is image uploading</p>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-3-basic-text-input/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-3-basic-text-input/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-3-basic-text-input/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a CMS with CodeIgniter: Part 2 Authentication</title>
		<link>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-2-authentication/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-2-authentication/#comments</comments>
		<pubDate>Tue, 08 May 2012 13:57:57 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodeIgnitor]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=128</guid>
		<description><![CDATA[I&#8217;ve discovered a really annoying video tutorial by nettuts, but it gets the job done. just be glad you don&#8217;t have to listen to the annoying voice over. if you really want to bash your ears, find the video here &#8230; <a href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-2-authentication/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve discovered a really annoying video tutorial by nettuts, but it gets the job done. just be glad you don&#8217;t have to listen to the annoying voice over. if you really want to bash your ears, find the video <a href="http://net.tutsplus.com/tutorials/php/easy-authentication-with-codeigniter/" target="_blank">here</a></p>
<p>First thing is to create a new Controller called admin.</p>
<p>1. In application/controllers, create a file called admin.php. in this file, add the following code:</p>
<pre>
&lt;?php if( !defined(&#039;BASEPATH&#039;)) exit(&#039;No direct script access allowed&#039;);
	class Admin extends CI_Controller
	{
		public function index()
		{
			$this-&gt;load-&gt;view(&#039;v_login&#039;);
		}
	}
?&gt;
</pre>
<p>2. Now you need to create the view for the login screen. In the view folder, create a file called v_login.php. insert some html code here to display your login UI. the tutorial suggested the code below:</p>
<pre>
&lt;html lang=&quot;en&quot;&gt;
	&lt;head&gt;
		&lt;meta charset=&quot;utf-8&quot;&gt;
		&lt;title&gt;Login&lt;/title&gt;
	&lt;/head&gt;

	&lt;body&gt;
		&lt;h1&gt;Login&lt;/h1&gt;
		&lt;?php echo form_open(&#039;admin&#039;); ?&gt;
			&lt;p&gt;
				&lt;?php echo form_label(&#039;Username&#039;, &#039;username&#039; ); ?&gt;
				&lt;?php echo form_input(&#039;username&#039;, &#039;&#039;, &#039;id=&quot;username&quot;&#039;); ?&gt;
			&lt;/p&gt;
			&lt;p&gt;
				&lt;?php echo form_label(&#039;Password&#039;, &#039;password&#039; ); ?&gt;
				&lt;?php echo form_password(&#039;password&#039;, &#039;&#039;, &#039;id=&quot;password&quot;&#039;); ?&gt;
			&lt;/p&gt;
			&lt;p&gt;
				&lt;?php echo form_submit(&#039;submit&#039;, &#039;Login&#039;); ?&gt;
			&lt;/p&gt;
		&lt;?php echo form_close(); ?&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>3. You need to alter the CodeIgniter autoload config. Open config/autoload and find the &#8216;libraries&#8217; object and add &#8216;databases&#8217; to it like so</p>
<pre>
$autoload['libraries'] = array('database');
</pre>
<p>also add url and form helpers by finding the helpers object and as follows:</p>
<pre>
$autoload['helper'] = array('url', 'form');
</pre>
<p>4. The next step is to add some validation so modify the admin controller and add the following code in the index function</p>
<pre>
$this->load->library('form_validation');
$this->form_validation->set_rules('username', 'Username', 'required|valid_email');
$this->form_validation->set_rules('password', 'Password', 'required');

if ( $this->form_validation->run() != false )
{
	// validation pass
}
</pre>
<p>You&#8217;ll also need to add the markup for the validation error in your login view.</p>
<pre>
&lt;div class=&quot;error&quot;&gt;&lt;?php echo validation_errors(); ?&gt;&lt;/div&gt;
</pre>
<p>5. next up is the database. you&#8217;ll need to create a new one however you prefer. i&#8217;ll use phpmyadmin. i&#8217;ve created an auto incrementing id field, a username field, password field, first and last name fields and a created field. a note when creating a timestamp field, do not enter a length for the field, phpmyadmin doesn&#8217;t like it. Once that&#8217;s done, manually enter one user into the db.</p>
<p>6. now you need a model for your controller to connect to. create a file in the application/models directory called m_admin.php and insert the following code:</p>
<pre>
&lt;?php
	class M_Admin extends CI_Model
	{
		function __contruct()
		{

		}

		public function verify_user( $username, $password )
		{
			$query = $this-&gt;db-&gt;where( &#039;username&#039;, $username )-&gt;where( &#039;password&#039;, sha1($password) )-&gt;limit(1)-&gt;get(&#039;users&#039;);

			if ( $query-&gt;num_rows &gt; 0 )
			{
				echo &#039;&lt;pre&gt;&#039;;
				print_r($query-&gt;row());
				echo &#039;&lt;/pre&gt;&#039;;
				return $query-&gt;row();
			}
			else
			{
				//error or empty
			}
		}
	}
?&gt;
</pre>
<p>7. now head back to the admin controller and load the model in by adding the following code: (swap the username and password out for your one)</p>
<pre>
$this->load->model('m_admin');
$this->m_admin->verify_user( 'username here', 'password here' );
</pre>
<p>8. you&#8217;ll need to alter the default database config in CodeIgnitor for this code to work. so open the database.php in the config directory and enter your database details. give it a test and it should spit out the first row from the db.</p>
<p>more to come soon&#8230;it&#8217;s bed time!</p>
<p>ok i&#8217;m back. so the next step is to take the actual user input. this is the same as using good ol $_POST.</p>
<p>9. replace the hard-coded username and password in the controller with $this->input->post(&#8216;username&#8217;) and $this->input->post(&#8216;password&#8217;) so the final line is</p>
<pre>
$this->m_admin->verify_user( $this->input->post('username'), ( $this->input->post('password') ) );
</pre>
<p>10. updating some config stuff. now this video changes the base url now which is something that should be done at the start. find the line that reads base_url and copy the root of your web site url into it. i&#8217;ll also change some security settings. </p>
<ul>
<li>xss should be set to true. this filters dodgy hacks from POST, GET and COOKIE data</li>
<li>csrf should also be set to true. this helps prevent attacks that use image tags to conduc http requests to trusted websites</li>
</ul>
<p>11. Next in the video, they store the logged in username into a session variable, except instead of using CodeIgniter for this, they use the php SESSION variable. strange. so i&#8217;ll use the CodeIgniter method instead.<br />
first load the library using the following command in the constructor:</p>
<pre>
public function __construct()
{
	parent::__construct();
	$this->load->library('session');
}
</pre>
<p>you&#8217;ll also need to modify the config and add your own encryption key. this should be a 32 character (256-bit) string made up of letters and numbers.</p>
<p>to store a custom entry into the session, in this case the username, do the following:</p>
<pre>
$this->session->set_userdata('username', $this->input->post('username') );
</pre>
<p>finally, redirect to the secure page using redirect(&#8216;welcome&#8217;)</p>
<p>12. now for a bit of fanciness, i&#8217;ll make it so the username field retains the value you entered if you enter an incorrect password. simply open the view class and change form_input for username to have a second parameter of set_value(&#8216;username&#8217;).</p>
<p>13. a logout function would be good so use the following code:</p>
<pre>
public function logout()
{
	$this->session->sess_destroy();
	$this->load->view('v_login');
}
</pre>
<p>so now there is a logout function ready for a button to call it.</p>
<p>14. now is a good time to modify the config to load the login page by default. open the routes file in the config folder and set the default controller to admin.</p>
<p>15. now i&#8217;ll make sure that only logged in users can access the welcome page. add a constructor and the following code:</p>
<pre>
public function __construct()
{
	parent::__construct();

	$this->load->library('session');
	if ( !$this->session->userdata('username') )
	{
		redirect( 'admin' );
	}
}
</pre>
<p>it&#8217;s probably a good idea to add this functionality to the login page as well so if you are already logged in, just redirect to the welcome page.</p>
<p>16. now i&#8217;ll move the auth check into a library file so it can be reused across lots of controllers. create a library file called authenticate.php and paste the following code:</p>
<pre>
&lt;?php if ( ! defined(&#039;BASEPATH&#039;)) exit(&#039;No direct script access allowed&#039;); 

class Authenticate
{
    public function checkLoggedIn()
    {
		$CI =&amp; get_instance();
		$CI-&gt;load-&gt;library(&#039;session&#039;);

		if ( !$CI-&gt;session-&gt;userdata(&#039;username&#039;) )
		{
			redirect( &#039;admin&#039; );
		}
    }
}
</pre>
<p>now in each secure controller you just use the following two lines in the constructor:</p>
<pre>
$this->load->library('authenticate');
$this->authenticate->checkLoggedIn();
</pre>
<p>17. cleaning up the url. this should be done first really. once i&#8217;ve had some sleep i&#8217;ll tidy up this tutorial. create a .htaccess file in the root of your ci install. this is quite tricky in windows as it doesn&#8217;t like .htaccess files but the quick work around is to copy the .htaccess from the ci application directory. paste the following rewrite code:</p>
<pre>
RewriteEngine on
RewriteCond $1 !^(index\.php!resources!robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</pre>
<p>now you don&#8217;t need the index.php in the url. you should also go into the config file and remove the index.php. just leave it blank. lastly i added a pretty url called logout so i don&#8217;t need to type admin/logout. i did this inside the routes file by adding the line:</p>
<pre>
$route['logout'] = 'admin/logout';
</pre>
<p>that&#8217;s it! again thanks to nettuts (even if the video was really annoying!) next up will be creating various user input modules for the CMS like text and images.</p>
<p>EDIT:<br />
I discovered a new problem. after you logout you can still get back into the secure area by using the browser back button due to caching. luckily it&#8217;s very easy to fix. put this line inside your secure constructors:</p>
<pre>
$this->output->set_header("Cache-Control: no-store, no-cache, must-revalidate");
</pre>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-2-authentication/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-2-authentication/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-2-authentication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Building a CMS with CodeIgniter: Part 1 Installation</title>
		<link>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-1-installation/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-1-installation/#comments</comments>
		<pubDate>Tue, 08 May 2012 12:18:20 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodeIgnitor]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=124</guid>
		<description><![CDATA[This tutorial series is more for my own benefit than anything else as I&#8217;ve decided to learn CodeIgniter and as with learning any technology, information is sprawled all over the web. I&#8217;ll be building a basic CMS using the CodeIgniter &#8230; <a href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-1-installation/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This tutorial series is more for my own benefit than anything else as I&#8217;ve decided to learn CodeIgniter and as with learning any technology, information is sprawled all over the web. I&#8217;ll be building a basic CMS using the CodeIgniter framework. The CMS will be simple and reusable so each component needs to be modular in nature.</p>
<p>This series assumes you have good knowledge of PHP, HTML, CSS and web development in general. You should also have an understanding of the MVC design pattern. I also wont be going into great detail into each process, but I will provide the links where i have got the information from so you can learn as much or as little as you  like.</p>
<p>For this series i&#8217;ll be using the latest version of CodeIgniter at the time of writing; 2.10.</p>
<h2>Installation</h2>
<p>1. head over to the CodeIgniter website <a href="http://codeigniter.com/">http://codeigniter.com/</a> and download the source.</p>
<p>2. extract the CodeIgniter files into an appropriate folder on your web server. if you want to work locally, use WAMP, MAMP or XAMPP.</p>
<p>3. open your installation in a web browser and you should get the screen below.</p>
<p><a href="http://rohanlatimer.com.au/blog/wp-content/uploads/2012/05/ci-install.png"><img class="aligncenter size-medium wp-image-126" title="ci-install" src="http://rohanlatimer.com.au/blog/wp-content/uploads/2012/05/ci-install-300x229.png" alt="CodeIgnitor Installed correctly" width="300" height="229" /></a></p>
<p>&nbsp;</p>
<p>ok that was easy. so next up is authentication. i&#8217;ll figure out how to create a simple login screen. check back soon.</p>
<p>&nbsp;</p>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-1-installation/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-1-installation/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/05/building-a-cms-with-codeigniter-part-1-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>FlashDevelop AS3 Deus Ex:HR syntax colour</title>
		<link>http://rohanlatimer.com.au/blog/2012/02/flashdevelop-as3-deus-exhr-syntax-colour/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/02/flashdevelop-as3-deus-exhr-syntax-colour/#comments</comments>
		<pubDate>Sat, 11 Feb 2012 01:24:13 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[as3]]></category>
		<category><![CDATA[FlashDevelop]]></category>
		<category><![CDATA[games]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=111</guid>
		<description><![CDATA[yep this is as nerdy as it gets people. i had some time to finally do a custom syntax colour scheme for flashdevelop, my tool of choice and here it is, based on Deus Ex:HR. Note this is only for &#8230; <a href="http://rohanlatimer.com.au/blog/2012/02/flashdevelop-as3-deus-exhr-syntax-colour/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>yep this is as nerdy as it gets people. i had some time to finally do a custom syntax colour scheme for flashdevelop, my tool of choice and here it is, based on Deus Ex:HR. Note this is only for AS3 and i just whipped it up so let me know if there are any oddities with it.</p>
<p><img class="aligncenter size-full wp-image-118" title="fdsyntax" src="http://rohanlatimer.com.au/blog/wp-content/uploads/2012/02/fdsyntax2.gif" alt="" width="650" height="564" /></p>
<p>&nbsp;</p>
<p>click <a href="http://rohanlatimer.com.au/blog/downloads/DeusExHRAS3.fdz">here</a> to download<br />
the font is called Square 721 BT and appears to be a free one. i grabbed the ttf from <a href="http://www.fontpark.net/en/font/square-721-bt/">here</a></p>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/02/flashdevelop-as3-deus-exhr-syntax-colour/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/02/flashdevelop-as3-deus-exhr-syntax-colour/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/02/flashdevelop-as3-deus-exhr-syntax-colour/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>planned obsolescence and printers</title>
		<link>http://rohanlatimer.com.au/blog/2012/02/planned-obsolescence-and-printers/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/02/planned-obsolescence-and-printers/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 07:15:07 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=108</guid>
		<description><![CDATA[home printers in my view are one of the most blatant examples of capitalism saying: &#8220;i don&#8217;t give a fuck about anything but money&#8221;. for starters, it&#8217;s nearly cheaper to buy a new printer, than get replacement cartridges. then they are just designed to &#8230; <a href="http://rohanlatimer.com.au/blog/2012/02/planned-obsolescence-and-printers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>home printers in my view are one of the most blatant examples of capitalism saying: &#8220;i don&#8217;t give a fuck about anything but money&#8221;. for starters, it&#8217;s nearly cheaper to buy a new printer, than get replacement cartridges. then they are just designed to stop working after a certain time.</p>
<p>take my Epson Stylus PHOTO TX700W. the other day it decide to spit out a message saying i needed to replace my ink pads and then refused to work. forget that the unit also has a scanner built in meaning you can&#8217;t use that anymore either. and so why can&#8217;t i just replace the ink pads? well they are <em>designed</em> to be only replaceable by a qualified technician (which i very much doubt even exists given the price of this level of printers).</p>
<p>so do you think i would just lay down and let Epson rape me printer style? fuck no! here&#8217;s what i&#8217;ve done. firstly, around 2 years ago (the printer is about 3 years old) i purchased a CISS from <a href="http://www.rihac.com.au/">http://www.rihac.com.au/</a>. since then, i haven&#8217;t even had to buy replacement ink. i&#8217;ve reset the ink sensor on the printer around 6 times, so i&#8217;m thinking that&#8217;s at least how many cartidges i&#8217;ve saved purchasing. so this stopped the INCREDIBLE waste of plastic in ink cartidges not to mention the cost &#8211; $139.99 for 6 colours or $26.99 for one on epson australia&#8217;s website compared with $130 for the CISS which comes with about 8 TIMES THE AMOUNT OF INK IN CARTIDGES.</p>
<p>and as for the replacement ink pad? i called bullshit and downloaded some software to reset the printers inkpad counter. a quick search of the web and i found this <a href="http://www.ziddu.com/download/11651514/PCmediksResetterTX700WbyOrTHoTaMiNe.rar.html">utility</a>. within seconds the error had gone and the printer was working again. this is just absolute bullshit and i know it&#8217;s not just Epson doing this.</p>
<p>so here is a message to Epson and the other printer companies openly engaging in planned obsolescence. GO FUCK YOURSELF.</p>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/02/planned-obsolescence-and-printers/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/02/planned-obsolescence-and-printers/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/02/planned-obsolescence-and-printers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making Photoshop a tilemap editor with ExtendScript</title>
		<link>http://rohanlatimer.com.au/blog/2012/02/making-photoshop-a-tilemap-editor-with-extendscript/</link>
		<comments>http://rohanlatimer.com.au/blog/2012/02/making-photoshop-a-tilemap-editor-with-extendscript/#comments</comments>
		<pubDate>Tue, 07 Feb 2012 10:06:08 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[game development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[photoshop]]></category>
		<category><![CDATA[ExtendScript]]></category>
		<category><![CDATA[Tilemap]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=97</guid>
		<description><![CDATA[i&#8217;ve been working on a basic actionscript tile engine for making 2d games for ages. i&#8217;ve played around with a few frameworks on the net, most notably flixel and while these tools are great, i just want something really simple. &#8230; <a href="http://rohanlatimer.com.au/blog/2012/02/making-photoshop-a-tilemap-editor-with-extendscript/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>i&#8217;ve been working on a basic actionscript tile engine for making 2d games for ages. i&#8217;ve played around with a few frameworks on the net, most notably flixel and while these tools are great, i just want something really simple. the tile engine itself is nearly ready and has been for some time now. the main issue has been an easy way of creating tilemaps. when searching for tools i just haven&#8217;t found anything that suits my liking so i thought i&#8217;d make my own. now if i could get funding to make a nice air app so everyone could use it for free i would, but because i&#8217;m flat out busy and have little time i decided just to make a little script  for photoshop that would output a tilemap txt file. it&#8217;s called tileshop and here&#8217;s how it works:</p>
<ul>
<li>arrange uniform tiles in photoshop, with each tile on it&#8217;s own layer</li>
<li>make sure each layer is named. if two layers (tiles) are the same, make sure they have the same name. using numbers will be the most efficient.</li>
<li>go to file &gt; scripts &gt; browse&#8230; and find the tileshop script.</li>
<li>enter the size of the tile in pixels ( at the moment it only supports square tiles )</li>
<li>select folder to save the tilemap and presto, tilemap generated!</li>
</ul>
<p>The tilemap simply stores the size and a CSV string of the tile ids. so very basic but it should do the trick!</p>
<p>here&#8217;s the script:</p>
<pre>
// tileshop.jsk
// @author rohanlatimer.com.au
// @version 1.0
// @date 07Feb2012

// enabled debugging by commenting out this script
//$.level = 1;

if( BridgeTalk.appName == "photoshop" )
{
// check a document is open
if( app.documents.length &gt; 0 )
{
// ask user for tile size
var userCancelled = false;

var dlg = new Window('dialog', 'Tileshop setup',[400,300,800,430]);
dlg.msgPnl = dlg.add('panel', [25,15,375,120], 'Welcome to tileshop 1.0!');
dlg.msgPnl.okBtn = dlg.msgPnl.add('button', [20,60,115,90],'OK', {name:'ok'});
dlg.msgPnl.cancelBtn = dlg.msgPnl.add('button', [225,60,325,90],'Cancel', {name:'cancel'});
dlg.msgPnl.titleSt = dlg.msgPnl.add('statictext', [15,20,210,40],'What size are your tiles? ');
dlg.msgPnl.titleSt = dlg.msgPnl.add('statictext', [287,20,320,40],"px");
dlg.msgPnl.titleEt = dlg.msgPnl.add('edittext', [215,20,285,40],0);
dlg.msgPnl.titleEt.active=true;

// Check that the number input is within the valid range.
// If OK - continue, else display an error message.
dlg.msgPnl.okBtn.onClick = function()
{
if(!isNaN(dlg.msgPnl.titleEt.text))
{
if((dlg.msgPnl.titleEt.text)&gt; 0)
{
dlg.close(0);
}
else
{
alert("Number must be between greater than 0!");
}
}
else
{
alert("Invalid number input!")
}
};

// Set the cancel variable to true if the user cancels the operation
dlg.msgPnl.cancelBtn.onClick = function()
{
userCancelled = true;
dlg.close(0);
};

// Display the dialog
buttonSelected = dlg.show();

if( !userCancelled )
{
var tileString = "size:" + dlg.msgPnl.titleEt.text + ";\rmap:";

// iterate through each layer and create a comma delimited string
for( var i = 0; i &lt; activeDocument.layers.length; i++ ) { if( !activeDocument.layers[i].allLocked &amp;&amp; !activeDocument.layers[i].isBackgroundLayer ) { if( i &gt; 0 )
{
tileString += ",";
}
tileString += activeDocument.layers[i].name;
}
}

tileString += ";";

try
{
var outputFolder = Folder.selectDialog( "Select a folder to save the tilemap" );
if( outputFolder == null )
{
alert( "Please select a folder" );
}
else
{
var of = new File( outputFolder + "\\tilemap.txt" );
of.open( "w" );
of.write( tileString );
of.close();

alert( "Tilemap saved!" );
}
}
catch( exception )
{
alert( "Please select a folder" );
}
}
}
else
{
alert( "Please open a document to export" );
}
}
else
{
alert( "This script is only for Photoshop!" );
}
</pre>
<p>download it here: <a href="http://rohanlatimer.com.au/blog/downloads/tileshop.jsx" target="_blank">tileshop.jsx</a></p>
<g:plusone href="http://rohanlatimer.com.au/blog/2012/02/making-photoshop-a-tilemap-editor-with-extendscript/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2012/02/making-photoshop-a-tilemap-editor-with-extendscript/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2012/02/making-photoshop-a-tilemap-editor-with-extendscript/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>2011 wrap up</title>
		<link>http://rohanlatimer.com.au/blog/2011/12/2011-wrap-up/</link>
		<comments>http://rohanlatimer.com.au/blog/2011/12/2011-wrap-up/#comments</comments>
		<pubDate>Mon, 19 Dec 2011 09:16:37 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[wrap up]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=85</guid>
		<description><![CDATA[no one probably gives two shits what i think was the best things to come out of this year, but hey it&#8217;s a good record for myself. so if you are reading this, give yourself a pat on the back &#8230; <a href="http://rohanlatimer.com.au/blog/2011/12/2011-wrap-up/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>no one probably gives two shits what i think was the best things to come out of this year, but hey it&#8217;s a good record for myself. so if you are reading this, give yourself a pat on the back for me. also note that not everything in this list was released in 2011, it&#8217;s just when i first experienced it. and remember, this is a list of my favourite things.</p>
<p><span style="color: #ff0000;"><strong>Console/PC Game of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: Deus-Ex: Human Revolution (PC)</em></span><br />
being a huge fan of the original and given invisible war was a let down, i was hugely sceptical of this one. the very nice augmented edition enticed me to pre-order &#8211; something i hadn&#8217;t done all year. and so entering was expectations set to zero, i was pleasantly surprised by the brilliant world square enix had created. they obviously took a lot of notes out of the original&#8217;s book and it showed. now if i can just get a new computer so i can run it at max settings&#8230;</p>
<p><span style="color: #ff0000;"><strong>Mobile Game of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: Phone Story (Android)</em></span><br />
this game is not so much a game but a cheeky and depressing lesson. it hits the nail right on the head and screams the message out with hilarity that makes you feel bad for laughing. hopefully this game starts a trend in this genre learning through games that stays far away from games in the 90s like &#8216;mario is missing&#8217;</p>
<p><span style="color: #ff0000;"><strong>Movie of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: In The Footsteps of Marco Polo (2008)</em></span><br />
Ok i don&#8217;t watch many movies. probably saw under 20 this year. and half of them on flights. and the ones i do watch are normally documentaries. so it comes with no surprise that a documentary wins. this one is about 2 insane americans who decide to follow the route of marco polo from venice to china and back again &#8211; avoiding air travel. they somehow get through Afghanistan and Iran with the help of local warlords. great watch if you like travel.</p>
<p><span style="color: #ff0000;"><strong>Album of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: Endgame by Rise Against</em></span><br />
No surprise here from a punk rocker. Brilliant flow. message stronger and clearer than ever and the vinyl edition sounds great. if you like punk or just rock music with a message, give this one a listen.</p>
<p><span style="color: #ff0000;"><strong>Book of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: The Shock Doctrine by Naomi Klein (2007)</em></span><br />
It&#8217;s a beast of a read and pretty heavy to digest, but once you get through this book, it will change the way you view economics and politics. thought provoking, scary and surreal, klein begins the book with a massive slap to the face and remains relentless throughout. not one you&#8217;ll want to put down. an eye opener.</p>
<p><span style="color: #ff0000;"><strong>Gig of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: One day as a lion (Prince of Wales)</em></span><br />
Out for the big day out, Zach de la Rocha and Jon Theodore played at St Kilda&#8217;s prince in a one off gig with all proceeds going to Queensland flood victims. Considering they only have one EP out i didn&#8217;t really know what to expect. Zach was his usual ball of intense anger screaming out lyrics from the self titled EP. Closing with the band/title track One Day as a Lion, the bass was an experience unto itself &#8211; I think most of the audiences hearts were moved if not emotionally, definitely physically!</p>
<p><span style="color: #ff0000;"><strong>Travel Desitination of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: Mimosa Rocks NP</em></span><br />
I randomly ended up here with Laurel on new years eve and subsequently the 1st day of the year and this is a great spot. I won&#8217;t say exactly where it is but you&#8217;re smart right? you&#8217;ll figure it out. And this spot beat out the New Zealand Ski fields, the Canadian Rockies and Central Australia &#8211; all great places. who says you need to go overseas to find great places?</p>
<p><span style="color: #ff0000;"><strong>Idiot of the year</strong></span><br />
<span style="color: #ff6600;"><em>Winner: The Australian public</em></span><br />
Why? for giving Tony Abbott a better approval rating than Julia Gillard. Ok Julia, isn&#8217;t doing a fantastic job at selling herself and the Labor party, but come on. Tony Abbott is an absolute moron. I would rather vote for Family First than this buffoon &#8211; actually nah i wouldn&#8217;t go that far, i&#8217;d just off myself instead. so if you are like me and consider Abbott a loser consider yourself excused from this award.</p>
<g:plusone href="http://rohanlatimer.com.au/blog/2011/12/2011-wrap-up/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2011/12/2011-wrap-up/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2011/12/2011-wrap-up/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AIR 3.0/FP 11.0 Mobile game test: Pure AS3 vs Flixel vs Starling</title>
		<link>http://rohanlatimer.com.au/blog/2011/10/air-3-0fp-11-0-mobile-game-test-pure-as3-vs-flixel-vs-starling/</link>
		<comments>http://rohanlatimer.com.au/blog/2011/10/air-3-0fp-11-0-mobile-game-test-pure-as3-vs-flixel-vs-starling/#comments</comments>
		<pubDate>Fri, 21 Oct 2011 09:57:39 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[AIR 3.0]]></category>
		<category><![CDATA[as3]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[FlashDevelop]]></category>
		<category><![CDATA[flashplayer11]]></category>
		<category><![CDATA[flixel]]></category>
		<category><![CDATA[games]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[starling framework]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=73</guid>
		<description><![CDATA[since the new air runtime is out for mobiles i thought i&#8217;d give it&#8217;s new performance benefits a speed test. i&#8217;ve created a simple demo which continuously generates a bitmap sprite and drops it down the screen at a random &#8230; <a href="http://rohanlatimer.com.au/blog/2011/10/air-3-0fp-11-0-mobile-game-test-pure-as3-vs-flixel-vs-starling/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>since the new air runtime is out for mobiles i thought i&#8217;d give it&#8217;s new performance benefits a speed test. i&#8217;ve created a simple demo which continuously generates a bitmap sprite and drops it down the screen at a random speed. on top of that each sprite rotates to add some extra strain on the cpu/gpu. once the sprite leaves the screen, it is destroyed. sprites are capped at 100 on screen at a time. i&#8217;ve also used my <a title="swfconsole" href="http://rohanlatimer.com.au/swfconsole" target="_blank">swfconsole</a> tool to track the fps.</p>
<p>my test device is an HTC Desire running 2.2.2. i don&#8217;t have an iphone and don&#8217;t really want to sign up to there development program so if someone has an iphone and wants to test this, send me an email and i&#8217;ll put the results up. i run the test on the phone for a minute and take the average fps score.</p>

    <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="swfobj_0" width="480" height="762" align="center">
      <param name="movie" value="http://rohanlatimer.com.au/blog/wp-content/uploads/2011/10/MobileFlashTest.swf" />
      <param name="align" value="center" />
      <!--[if !IE]>-->
      <object type="application/x-shockwave-flash" data="http://rohanlatimer.com.au/blog/wp-content/uploads/2011/10/MobileFlashTest.swf" width="480" height="762" align="center">
      <!--<![endif]-->
        
      <!--[if !IE]>-->
      </object>
      <!--<![endif]-->
    </object>

<p>the demo was built using FlashDevelop and following this very quick and ace <a href="http://www.photonstorm.com/archives/2431/creation-of-a-mobile-app-without-the-flash-ide-for-all-flashdevelop-lovers" target="_blank">tutorial</a>. i decided to test out the performance of pure as3 with no additional libraries, the <a href="http://flixel.org/" target="_blank">flixel</a> framework and the <a href="http://www.starling-framework.org/" target="_blank">starling</a> framework. and here are the results: *drumroll*</p>
<p><strong>Pure AS3</strong><br />
i deliberately didn&#8217;t use any blitting techniques in my demo as this is pretty much what flixel will do for me so this is simply a bunch of Sprite classes with embedded bitmaps falling down the screen.</p>
<p>CPU: 20 fps<br />
GPU: 18 fps<br />
File size:  60kb (not including air runtime)</p>
<p><strong>Flixel</strong><br />
i had some pretty high hopes for flixel as i&#8217;ve used it before a few times and its fast. in this case it was too, however it&#8217;s only good for pixel based games as it was actually slower than pure as3 at full resolution (zoom 1). at a zoom level of 2, i got the following results:</p>
<p>CPU: 25 fps<br />
GPU: 16 fps<br />
File size:  112kb (not including air runtime)</p>
<p><strong>Starling</strong><br />
this is the new GPU enabled library and unfortunately it doesn&#8217;t work yet :( most likely due to AIR for mobile not supporting stage3D yet. apparently it will be available sometime early next year according to Adobe. the demo kind of worked, but the viewport was totally screwed. i&#8217;ll post an update once stage3D is available for mobile. alternatively, if anyone has been able to get it to work, please let me know!</p>
<p>&nbsp;</p>
<p><strong>winner: </strong><br />
well there isn&#8217;t really any clear cut winner. choose pure as3 if the res matters, otherwise go for flixel for pixel based games. as for starling, we&#8217;ll just have to wait and see&#8230;</p>
<g:plusone href="http://rohanlatimer.com.au/blog/2011/10/air-3-0fp-11-0-mobile-game-test-pure-as3-vs-flixel-vs-starling/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2011/10/air-3-0fp-11-0-mobile-game-test-pure-as3-vs-flixel-vs-starling/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2011/10/air-3-0fp-11-0-mobile-game-test-pure-as3-vs-flixel-vs-starling/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>tutorial: twitter hashtag display with jquery</title>
		<link>http://rohanlatimer.com.au/blog/2011/10/tutorial-twitter-hashtag-display-with-jquery/</link>
		<comments>http://rohanlatimer.com.au/blog/2011/10/tutorial-twitter-hashtag-display-with-jquery/#comments</comments>
		<pubDate>Wed, 19 Oct 2011 06:21:34 +0000</pubDate>
		<dc:creator>ro</dc:creator>
				<category><![CDATA[css]]></category>
		<category><![CDATA[html 5]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[social networks]]></category>
		<category><![CDATA[tutorials]]></category>

		<guid isPermaLink="false">http://rohanlatimer.com.au/blog/?p=62</guid>
		<description><![CDATA[so i had an idea for a friend&#8217;s party to have a live twitter feed &#8211; kind of like Q&#38;A if you know that program on abc. the idea was to have a constant stream of tweets so people could &#8230; <a href="http://rohanlatimer.com.au/blog/2011/10/tutorial-twitter-hashtag-display-with-jquery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>so i had an idea for a friend&#8217;s party to have a live twitter feed &#8211; kind of like Q&amp;A if you know that program on abc. the idea was to have a constant stream of tweets so people could see what&#8217;s going on at the party. yeah pretty nerdy party i know, but it also gave me an excuse to try out the twitter API and a bit of jquery.</p>
<p>discovering how to do this on the internet actually took quite a bit of searching as both twitter and jquery have a bazillion articles on them so i decided to make this tutorial.</p>
<p>before you start, check out how it works <a title="twitterparty" href="http://rohanlatimer.com.au/lab/twitterparty/demo/" target="_blank">here</a></p>
<p><strong>step 1. create the html</strong><br />
this bit is the easiest part. the html can be anything. it&#8217;s the jquery that does all the work. just make sure you have an html file with a linked css file.</p>
<pre>
&lt;!DOCTYPE html&gt;
&lt;html lang="en"&gt;
&lt;head&gt;
&lt;meta charset="utf-8"&gt;
&lt;title&gt;Twitter Party&lt;/title&gt;
&lt;link rel="stylesheet" href="styles.css"/&gt;
&lt;script type="text/javascript" src="jquery-1.6.4.min.js"&gt;&lt;/script&gt;
&lt;script type="text/javascript" src="twitterparty.js"&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div id="tweets"&gt;

&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>the important parts are lines 6 &#8211; 8 and a having a div with id of &#8220;tweets&#8221; (although you can change this if you don&#8217;t like it).</p>
<p><strong>step 2. calling the twitter API</strong><br />
so first thing you need to do is grab some tweets from twitter. for this we&#8217;ll use jquery since we&#8217;ll be using it for some visual effects as well. you first need to make sure jquery is ready to use so you can use the following code:</p>
<pre>
(function() {
})();
</pre>
<p>this is a shortcut for the jquery document.ready function. if you&#8217;re not sure what i&#8217;m talking about, search for it and you&#8217;ll find stupid amounts of resources on it. with jquery ready to go, we need to call the twitter api with the following call:</p>
<pre>
$.getJSON( "http://search.twitter.com/search.json?q=%23hashtag&amp;result_type=recent&amp;rpp=5&amp;callback=?", {}, function (data)
{
$.each(data.results, handleTweets);
});
</pre>
<p>we&#8217;ve just used the jquery function getJSON which returns a set of data in the JSON format. you need to provide it with a url, a data set (in this case empty) and a callback function for when the function is complete. for the url, check the twitter api <a href="https://dev.twitter.com/docs/api/1/get/search">https://dev.twitter.com/docs/api/1/get/search</a>. you&#8217;ll need to replace &#8216;hashtag&#8217; with your own hashtag (don&#8217;t include the #. that&#8217;s what %23 is). here&#8217;s a breakdown of the url parameters:</p>
<ul>
<li>result_type: here we are forcing twitter to return the most recent tweets</li>
<li>rpp: the number of tweets to get in one call. you might want to increase this if it&#8217;s a very popular topic.</li>
<li>callback: this forces a JSONP return which allows us to make a request from a different server than the twitter server.</li>
</ul>
<p>as for the callback function, we use the jquery $.each function to send the data to a function to handle and display our tweets.</p>
<p><strong>step 3. show me the tweets</strong><br />
so now you need a handler for the tweets. this isn&#8217;t too tricky so check out the code:</p>
<pre>
function handleTweets( key, data )
{
// use jquery to add html to the page
$( '#tweets' ).prepend( "&lt;article&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;span class='user'&gt;@" + data.from_user + "&lt;/span&gt; " + data.text + "&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/article&gt;" );

// hide the tweet so it can be animated in
$( article ).hide( 0 );

$( article ).slideDown( 500 );
}
</pre>
<p>this code grabs the data for twitter and creates a new article tag (html5) to put the message in. it also includes the user name wrapped in a span for some custom styling. so if you want to check what data you can get from twitter feeds, check the api link above. it&#8217;ll show you a break down of the result set and the corresponding name value pairs.</p>
<p>for this example we only use the &#8216;text&#8217; and &#8216;form_user&#8217; values to populate our article tag. note that i have used a table for vertical centering of the text in this demo. once the html has been created, it&#8217;s then a matter of animating it nicely. first you need to hide it using jquery, then use your favourite animation to bring it it. i simply used a slideDown which was effective enough for me. for more info check out <a href="http://api.jquery.com/category/effects/">http://api.jquery.com/category/effects/</a></p>
<p><strong>step 4. handling multiple tweets</strong><br />
this is where it gets tricky. you&#8217;ll need to modify your existing code and add in a number of timers. do not use the jquery delay function. this only works on a single element. since we will be creating many elements, this will not work, instead you&#8217;ll need to use the javascript setTimeout to delay animations. anyways, check the complete code here:</p>
<pre>
* twitter party
* @author rohanlatimer.com.au
*/

var HASHTAG = 'ows'; // don't include the #
var UPDATE_INTERVAL = 2000; // how often to update the hash tag in milliseconds
var MAX_TWEETS = 10; // max number of tweets at a time. make this larger if the topic is popular
var ANIM_SPEED = 500; // speed of animation

var tweets = new Array();
var count = 0;
var tweets_per_call = 0;
var firstID = -1;

(function() {

// call the twitter api on a set interval
setInterval( function()
{
$.getJSON( "http://search.twitter.com/search.json?q=%23" + HASHTAG + "&amp;result_type=recent&amp;rpp=5&amp;callback=?", {}, function (data)
{
tweets_per_call = data.results.length;
firstID = -1;
// for each response, create a visual tweet
$.each(data.results, handleTweets);
});
}, UPDATE_INTERVAL );
})();

// handle the data from twitter
function handleTweets( key, data )
{
tweetFound = false;

// see if tweet already exists, if so don't handle it and exit
for( var i = 0; i &lt; tweets.length; i++ )
{
if( tweets[ i ].tweet == data.text )
{
tweets_per_call--;
return;
}
}

// increase tweet counter
count++;

// if its the first tweet in a request, set it to the current counter
if( firstID == -1 )
{
firstID = count;
}

// add tweet to array
tweets.push( { id : count, tweet : data.text } );

// add tweet to page
addTweet( count, data );

// remove the oldest tweet if there are more than
if( tweets.length &gt; MAX_TWEETS )
{
$( '#' + tweets[0].id ).hide( ANIM_SPEED, removeTweet( tweets[0].id ) );
tweets.shift();
}
}

// add tweet to html
function addTweet( id, data )
{
var delayTime = ANIM_SPEED;

// set delay time for each tweet
delayTime = ( id - firstID ) * ANIM_SPEED;

// use jquery to add html to the page
$( '#tweets' ).prepend( "&lt;article id='" + id + "'&gt;&lt;table&gt;&lt;tr&gt;&lt;td&gt;&lt;span class='user'&gt;@" + data.from_user + "&lt;/span&gt; " + data.text + "&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/article&gt;" );

// hide the tweet so it can be animated in
$( '#' + id ).hide( 0 );

// delay the display of the tweet until the ones in front of it have finished
setTimeout(function()
{
$( '#' + id ).slideDown( ANIM_SPEED );
}, delayTime);

}

// remove a tweet
function removeTweet( id )
{
$( '#' + id ).remove();
}
</pre>
<p>i also added some variables in here to make modifying it a bit easier.</p>
<p><strong>step 5. style it up</strong><br />
now you just need to make it pretty. first you want to style the container. you&#8217;ll want to change the height and width of this if you want to make a little widget for your site. also set the overflow to hidden.</p>
<p>then you just need to style the article element to change the background and text colour. you can also edit the user name using the .user class.</p>
<p>note i&#8217;ve also added table styling if you need it. you could always use fixed margins instead of tables if you prefer.</p>
<p>the code:</p>
<pre>
*
{
border: 0px;
padding: 0px;
margin: 0px;
}

html, body, #tweets
{
overflow: hidden;
font-family: Verdana, Arial, sans-serif;
font-size: 17px;
}

#tweets
{
position: absolute;
width: 900px;
left: 50%;
margin-left: -450px;
top: 20px;
color: #FFF;
}

/* each tweet box */
article
{
width: 900px;
height: 80px;
background-color: #222;
border-radius: 0px;
margin-bottom: 40px;
}

table
{
height: 100%;
width: 100%;
}

td
{
vertical-align: middle;
padding: 0px 20px 0px 20px;
}

/* twitter user name */
.user
{
font-weight: bold;
font-size: 20px;
color: #7e9137;
}
</pre>
<p>and that&#8217;s it.<br />
download source <a title="twitterparty source" href="http://rohanlatimer.com.au/lab/twitterparty/twitterparty.zip">here</a></p>
<g:plusone href="http://rohanlatimer.com.au/blog/2011/10/tutorial-twitter-hashtag-display-with-jquery/"  size="standard"   annotation="none"  ></g:plusone>
<!-- This is the start of the WP Twitter Button code -->
<div id="rk_wp_twitter_button" style="margin: 0px 0px 0px 0px; float: left"><a href="http://twitter.com/share" class="twitter-share-button" data-url="http://rohanlatimer.com.au/blog/2011/10/tutorial-twitter-hashtag-display-with-jquery/" data-count="horizontal" data-via="rohanlatimer">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script></div>
<!-- This is the end of the WP Twitter Button code -->

]]></content:encoded>
			<wfw:commentRss>http://rohanlatimer.com.au/blog/2011/10/tutorial-twitter-hashtag-display-with-jquery/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

