The GLUEineractive Blog http://www.gluei.com/blog A blog about CakePHP, Web Dev, the Internet and More. en-us Thu, 20 Nov 2008 18:37:15 GMT CakePHP Freshbooks - My new best friend http://www.gluei.com/blog/view/10 <p>If you do any sort of freelance work, you'll quickly run in to some logistical headaches. Namely, creating estimates, sending invoices and getting paid. You'll often have clients scattered all over the country, trying to coordinate client relationships &amp; paperwork quickly turns in to a massive headache.&nbsp; I ran in to the same issue, until I discovered <a href="http://www.freshbooks.com" mce_href="http://www.freshbooks.com">Freshbooks</a>.</p><p><a href="http://www.freshbooks.com" mce_href="http://www.freshbooks.com"><img src="http://farm4.static.flickr.com/3194/2991558645_8017318320_o.gif" mce_src="http://farm4.static.flickr.com/3194/2991558645_8017318320_o.gif"></a></p><p>Freshbooks is your one stop shop for all your freelance needs. You get to create lists of clients with contact information, easily send estimates to them &amp; track their payments to you.&nbsp; This is a service that a lot of websites provide, but what really impresses me with Freshbooks are the little things.</p><ul><li>Your clients can log in to your own branded (colors + logo) account center, where they can view their estimates and pay their invoices.</li><li>Freshbooks integrates in to a dozen payment gateways, including Verisign, Authorize.net &amp; Paypal.</li><li>You can upload your print-quality logo, and Freshbooks wil snail mail your clients your invoices for you!</li><li>Freshbooks also lets you track your expenses like hosting, which you can then rebill your clients for.</li><li>Time tracking is included, which isn't unheard of, but Freshbooks gives you OSX and Vista widgets to help you track your time.</li><li>Freshbooks even has a support system where your clients can open tickets, you can track the time on those tickets and then bill your clients for that time.</li></ul><p>I could go on and on, but you get the idea.&nbsp; Freshbooks takes all the historically confusing and time consuming tracking needs of sending estimates and invoices to your clients, and offers a solidified piece of tracking software that's both easy to use and highly powerfull. I don't want to have to worry about emailing invoices, tracking clients and trying to figure out if I got paid or not.&nbsp; That's why I use <a href="http://www.freshbooks.com" mce_href="http://www.freshbooks.com">Freshbooks</a>, it takes care of that for me. </p> Mon, Sep 8th 2008, 22:51 PDT http://www.gluei.com/blog/view/10 Using jQuery Inside Your Firefox Extension http://www.gluei.com/blog/view/11 <p>For a project a work we've been building a Firefox extension. It's slow, tedious work, with lots of time spent in the breakpointer functionality of <a href="http://www.mozilla.org/projects/venkman/" mce_href="http://www.mozilla.org/projects/venkman/">Venkman</a>. Thankfully Firefox extensions are basically javascript, and as I heard rumors of, you <i>can</i> embed <a href="http://jquery.com/" target="_blank" mce_href="http://jquery.com/">jQuery</a> inside of one. </p><p>How? Well it's quite simple. In your overlay.xul file, just include it like you would any other js file.</p><code class="source">&lt;script type="application/x-javascript" src="chrome://extensionname/content/jquery-1.2.6.min.js" /&gt;</code><p>Yup, that's it! Now you have access to all the usual jQuery functionality like <code>element.click()</code>, <code>element.attr()</code> and even the <code>$.ajax</code> calls, all within the scope of your extension. Thus, you can write extension code like this:</p><code class="source">$('.toggle').attr('disabled', true);</code><p>Where it will select all XUL elements in your extension with the class <code>toggle</code> and set the disabled attribute to true.</p><p>If you want to have access to the browser DOM, you can access it via the <a href="https://developer.mozilla.org/en/DOM/document.defaultView" target="_blank" mce_href="https://developer.mozilla.org/en/DOM/document.defaultView"><code>document.defaultView</code></a> attriute globally.&nbsp; Most times the defaultView variable is available inside of the event object if you've bound to one. Then, in order to effect the browser DOM, all you have to do is make use of the (often ignored) 2nd parameter of the <a href="http://docs.jquery.com/Core/jQuery#expressioncontext" mce_href="http://docs.jquery.com/Core/jQuery#expressioncontext">$ function</a>, the conext you'd like jQuery to work in. </p><p>In our case it's the browser's DOM.&nbsp; For example, to highlight all links on the page that are rel=nofollow, you just have to do this:</p><code class="source">doc = document.defaultView;<br>jQuery("a[rel='nofollow']", doc).css({border: 'dotted 1px red', backgroundColor: 'pink'});</code><p>Now you have the power!</p> Thu, Oct 30th 2008, 22:17 PDT http://www.gluei.com/blog/view/11 Using a Site Layout with the Sinatra Web Framework http://www.gluei.com/blog/view/9 <p>The Sinatra web framework is very elegant, yet powerful. Once installed, all you have to do is map urls coming to Ruby functions, inside of which you can write ruby code to do just about anything.</p><code class="source">get '/' do<br>&nbsp; haml :index<br>end</code><p>In this exampple, it uses Sinatra's built in haml function to run the <code>./views/index.haml</code> template.&nbsp; But you can add whatever ruby code inside the functions you want, such as "hello world," ActiveRecord or accept a form POST.</p><p>The one thing missing was the ability to have a sitewide layout, that would wrap the output from your routing. I searched the <a href="http://www.sinatrarb.com/docs/sinatra/index.html" mce_href="http://www.sinatrarb.com/docs/sinatra/index.html">Sinatra documentation</a> over and over, finally finding the <a href="http://www.sinatrarb.com/docs/sinatra/files/lib/sinatra_rb.html#M000099" mce_href="http://www.sinatrarb.com/docs/sinatra/files/lib/sinatra_rb.html#M000099">layout function</a>.&nbsp; There wasn't much there, but playing around with the code I managed to figure out how it works. </p><p>By default, Sintara will look for a <code>./views/layout.ext</code> file to use as a template, where "ext" is replaced with your templating-system specific extenstion. For instance, if you're using <a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/" mce_href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/">erb</a> it's <code>layout.erb</code> and if it's <a href="http://haml.hamptoncatlin.com/" mce_href="http://haml.hamptoncatlin.com/">haml</a> you use <code>layout.haml</code>. If you just return markup with your route, it <b>will not</b> use any template file. </p><p>Now, if you want to use a <i>different</i> layout than the standard one, you'll have to specify that in your template function like so.<br></p><code class="source:">haml :index, {:layout =&gt; :special}</code><p>That's it!</p><p>Hope this helps some people trying to figure out layouts in Sinatra.&nbsp;</p> Thu, May 1st 2008, 21:31 PDT http://www.gluei.com/blog/view/9 Why You Should Use Persistent Connections with MySQL http://www.gluei.com/blog/view/8 <p>If you do a search at Google for <a href="http://www.google.com/search?hl=en&amp;client=firefox-a&amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;hs=3F0&amp;q=connecting+to+MySQL+PHP&amp;btnG=Search" mce_href="http://www.google.com/search?hl=en&amp;client=firefox-a&amp;rls=org.mozilla%3Aen-US%3Aofficial&amp;hs=3F0&amp;q=connecting+to+MySQL+PHP&amp;btnG=Search">connecting to MySQL with PHP</a>, every single tutorial you'll find uses the <code><a href="http://www.php.net/manual/en/function.mysql-connect.php" mce_href="http://www.php.net/manual/en/function.mysql-connect.php">mysql_connect()</a></code> function.&nbsp; This makes total sense really, since it is the defacto-standard connection function for PHP.&nbsp; And for most applications (read: low-volume) it works well, and most developers never have a problem with it.&nbsp; You can start to run in to problems when your site starts getting traffic.<br></p><p>This same problem recently happened at my day job.&nbsp; Our current site was mostly coded by the previous head developer, who more-or-less designed, developed and coded the entire thing himself.&nbsp; While this is an amazing feat to say the least, the site just wasn't coded as efficiently as it could be.&nbsp; The old developer just didn't have time or expertise with CakePHP to do a thorough and efficient job.&nbsp; A lot of the pages on the site generated lots MySQL queries, often times in the triple-digits.&nbsp; Initially we didn't really notice a problem with the site.&nbsp; Sometimes things were slow, but because our traffic was relatively low and we were on very high-performance hardware, speed and efficiency wasn't an issue.</p><p>That's changed over the last year, however.&nbsp; Our traffic grew by about 40%, tables were getting bigger with more rows.&nbsp; As such, our site was starting to slow down.&nbsp; I did what I could optimizing pages to minimize the load on the database, but things were still slow.&nbsp; Watching the load on the database server, it would often spike to 8-10 with 90% CPU usage.&nbsp; Not good. </p><p>It's about that time that I decided to look in to persistent connections.&nbsp; In a nutshell, persistent connections keep (Apache's) connections to the database open even after the data transfer has ended.&nbsp; Database connections and closes are expensive for the database, so keeping them around (making them <i>persistent</i>) to reuse instead is where you get your performance imporvement.</p><p>Happy with my research, I decided to give it a shot.&nbsp; I switched over our <code>mysql_connect()</code> to <code><a href="http://www.php.net/manual/en/function.mysql-pconnect.php" mce_href="http://www.php.net/manual/en/function.mysql-pconnect.php">mysql_pconnect()</a></code>, restarted our database &amp; web server and waited.&nbsp; The results were <b><i>magical</i></b>.&nbsp; Load &amp; CPU usage on the DB server lowered, the load on the web server lowered and the site was at least 2-4 times faster.&nbsp; Awesome.</p><p><b>Persistent connections are faster than normal connections.</b>&nbsp; So please use them.</p><h2>Some things to think about&nbsp;</h2><p>This isn't to say that persistent connections don't come with their own set of problems.&nbsp; There are a few things that you'll need to consider when using persistant connections.</p><ol><li><b>Transacitons</b> - Since the connection to MySQL is continually open, if an Apache process begins a transaction and it never commits or rolls back, all of the mysql queries that particular connection does will be considered part of that same transaction.&nbsp; This is bad.&nbsp; You can solve this by creating a register_shutdown_function() that does a database rollback.&nbsp; The <a href="http://www.php.net/manual/en/features.persistent-connections.php" mce_href="http://www.php.net/manual/en/features.persistent-connections.php">PHP manual page on persistent database connections</a> has a fair amount about this. </li><li><b> Open Threads</b> - Since you're only going to have a limited number of MySQL connections open at a time, you have to be careful not to run in to a situation where Apache is utilizing all your current database connections and it then tries to connect to MySQL again.&nbsp; There won't be an available MySQL connection for it, and thus Apache will be blocked and has to wait until it can serve the request.&nbsp; Just make sure that there is always slightly more database threads than Apache threads. </li><li><b>mod_php</b> - Persistant connections are only supported if you're using PHP in the mod_php variety, and not the CGI wrapper.&nbsp; Most shared hosts and default PHP setups use mod_php, so you should be in the clear with this.</li></ol><p>In general, though, persistent connections are pretty safe.&nbsp; Give them a shot on your web app and see how it preforms.</p> Fri, Apr 4th 2008, 21:33 PDT http://www.gluei.com/blog/view/8 CakePHP Best Practices: Rethinking the hasAndBelongsToMany Association http://www.gluei.com/blog/view/7 <p>When you're first learning about CakePHP (or any kind of MVC associations), the hasAndBelongsToMany relationship is a powerful one.&nbsp; In a nutshell, it allows you to associate one model to another, without making it an exclusive association.&nbsp; So for example...if you're building a tagging system for your bloging platform, a Post --hasAndBelongsToMany--&gt; Tags.&nbsp; The <a href="http://manual.cakephp.org/chapter/models" mce_href="http://manual.cakephp.org/chapter/models">CakePHP manual chapter on models</a> has more information if you're still a little confused.</p><p>And in most cases, this association works well.&nbsp; You define a "join table" that contains 2 fields, as in our blogging example, a <code>post_id</code> and <code>tag_id</code> columns.&nbsp; Thanks to Cake's built in framework code to handle this association, you're up and running in no time.</p><p>But what happens when you need to store more information about the association?&nbsp; For example, imagine if you're building an online ordering system.&nbsp; Orders can contain multiple products, so you'll need to say that an Order --hasAndBelongsToMany--&gt; Item.&nbsp; But each Item/Order association also needs to have some other ancillary information - such as the price the customer paid for that item on that order.&nbsp; With the traditional hasAndBelongsToMany relationship, you can't do that.</p><p>To solve this, we're going to borrow from Rails once again, utilizing the principal of their <a href="http://wiki.rubyonrails.org/rails/pages/Beginner+Howto+on+has_many+:through" mce_href="http://wiki.rubyonrails.org/rails/pages/Beginner+Howto+on+has_many+:through">hasMany :through</a> functionality.</p><p>Basically, we're going to upgrade our hasAnyBelongsToMany association and put a full fledged model as the join.&nbsp; So rather than having just a join table that associates two models, we're going to put a real model in between and associate the two other models to <i>it</i>.&nbsp; As in above case of our online ordering system, we'll stick a <code>LineItem</code> model in between.</p><p>First, lets define our Order model.</p><p><code class="source">class Order extends AppModel {<br><br>&nbsp; var $name = 'Order';<br>&nbsp; var $hasMany = array('LineItem');<br> <br>}</code></p><p>Now our Item model.</p><code class="source">class Item extends AppModel {<br><br>&nbsp; var $name = 'Item';<br>&nbsp; var $hasMany = array('LineItem');<br> <br>}</code><p>Note that an Order &amp; Item --hasMany--&gt; LineItem?&nbsp; Well here is the LineItem model.</p><code class="source">class LineItem extends AppModel {<br><br>&nbsp;&nbsp;&nbsp; var $name = 'LineItem';<br>&nbsp;&nbsp;&nbsp; var $belongsTo = array('Order', 'Item');<br><br>}</code><p>Basically, now an Order has many LineItems.&nbsp; And each Item is also has many LineItems.&nbsp; Conversly, each LineItem belongs to an Order and an Item.</p><p>The cool part about is that since your "join table" is now a full fledged model, you get all the things that come with a model - like a real database table, other associations, attributes, primary keys, etc.&nbsp; Adding that "price" attribute for each Item joined to an Order is as simple as adding a <code>price</code> column to the <code>line_items</code> table. </p><p>With this method, however, comes some lack of convenience.&nbsp; With the default Cake hasAndBelongsToMany relationship, if you want to save an Order and all its associated tags, you just add an input field (like a multiple select) with <code>data[Item][Item]</code> in the Post form, and Cake does the rest.</p><p>With this new method, you can still have the multiple select in your Order add form, but you'll have to add some extra code to handle the incoming <code>data[Item][Item]</code> data and save an associated LineItem models.&nbsp; It's just a little bit of overhead, but well worth the flexibility you get with the hasMany :through method. </p> Thu, Mar 27th 2008, 21:33 PDT http://www.gluei.com/blog/view/7 CakePHP Best Practices: Fat Models and Skinny Controllers http://www.gluei.com/blog/view/6 <p>Since I've been doing a lot of <a href="http://www.rubyonrails.org" target="_blank" mce_href="http://www.rubyonrails.org">Rails</a> work, I've been doing a lot of reading on Rails and MVC frameworks best practices.&nbsp; One of the base principals the Rails community that I've come across more than once is the "Fat models and skinny controllers" methodology.&nbsp; Say what?&nbsp; Let me tell you. </p><p>When you first start working with MVC frameworks, you're first instinct is to put nearly all your code in the controller.&nbsp; It makes sense really - it's the first line of defense when someone runs a function on your site and it has direct access to the model &amp; all of its useful helper functions.</p><p>The problem with this methodology rears its head after a few days of coding.&nbsp; Your models are still very skinny, but your controllers end up being hundreds of lines long. They're "fat", full of lines and lines of code like this...</p><code class="source">$review_cond = "Review.model = 'Artist' AND Review.foreign_key = '$id'";<br>$reviews = $this-&gt;Artist-&gt;Review-&gt;findAll($review_cond, "Review.id, Review.review, Review.score, Review.created, User.id, User.name", "Review.created DESC", 5, null, 0);<br>foreach ($reviews as $review) {<br>&nbsp;&nbsp;&nbsp; $this-&gt;mrClean-&gt;cleanArray($review['Review']['review']);<br>}<br>$this-&gt;set('reviews', $reviews);<br>$this-&gt;set('other_reviews', $this-&gt;Artist-&gt;Review-&gt;findCount($review_cond)-5);</code><p>Good code should be easy to read and should communicate intent quickly.&nbsp; That code does neither.&nbsp; I actually wrote the code above a long time ago and it took <i>me</i> 2 minutes just now to figure out what that code did!&nbsp; That's not good.&nbsp; Now imagine if you had a coworker or someone else tried to read that code?&nbsp; They'd be at a total loss. </p><p>While Cake's built in model functions like <code>findAll()</code> are nice and very helpful (we'll still use them when we recode this), when you fill their parameters chaulk full of hard to read arrays and long strings, all meaning of what that line of controller-code does goes out the window. </p><p>The answer to fat controllers is to make your model fat instead.&nbsp; The model is supposed to represent some object.&nbsp; In the above code sample we're trying to get an Artist's most recent reviews, so we should be asking the Artist <i>model</i> to do that for us.</p><p>With that in mind, here is the same functionality achieved from the previous example put in the Artist model...</p><code class="source">function getRecentReviews($number = 5, $sort = "created DESC") {<br>&nbsp;&nbsp;&nbsp; $conditions = "Review.model = 'Artist' AND Review.foreign_key = '".$this-&gt;id."'";<br>&nbsp;&nbsp;&nbsp; $fields = "Review.id, Review.review, Review.score, Review.created, User.id, User.name";<br>&nbsp;&nbsp;&nbsp; $this-&gt;Review-&gt;recursive = -1;<br>&nbsp;&nbsp;&nbsp; return $this-&gt;Review-&gt;findAll($conditions, $fields, $this-&gt;name.".$sort", $number);<br>}</code><p>Then in your controller, the only code you need to write is...</p><code class="source">$this-&gt;Artist-&gt;getRecentReviews(5);</code><p>Muuuuuuuuch simpler.&nbsp; Anyone coming along can easily tell what that section of code in the controller is doing - simply by reading the name of the function.&nbsp; This is what people are talking about then they say code is "self documenting" - the name of the function tells you what the code is doing.&nbsp; The same code that <i>was</i> in the controller is still there and now in the model.&nbsp; By putting it there, it forces you to think how to abstract its functionality &amp; makes it reusable for the future. </p><p>Skinny controllers and fat models <a href="http://cakebaker.42dh.com/#post-562" target="_blank" mce_href="http://cakebaker.42dh.com/#post-562">isn't exactly a new idea</a> in the CakePHP world, but it is one that's facing slow adoption.&nbsp; As I see it, the main reason for the lack adoption is the absence of model behaviors and focus on controller components in the current stable version of Cake (1.1).&nbsp; Without some custom coding, there really isn't a way to quicky and easily utilize 3rd party code to extend your model and inherit additional functionality.&nbsp; Thus, you think of models only as a place to declare associations and validation.</p><p>People coding in 1.1 still make heavy use of components and as such get used to putting a large portion of their code in the controller.&nbsp; That will change as 1.1 gives way to 1.2, and CakePHP and its community evolve in to a more robust and adult web framework, but for right now try your hardest to have fat models and skinny controllers. </p> Tue, Jan 22nd 2008, 21:30 PDT http://www.gluei.com/blog/view/6 10 Steps to Becoming a Professional Web Developer http://www.gluei.com/blog/view/3 <p>When I started my day job as a web developer at a Seattle-based SEO company, I was assisting the one and only other developer at the company. He had been the sole developer for the company since they started doing web dev, and as such did things they way he'd always done them. Since I had learned most of my skills doing small time freelance work, our development process was the same as thousands of others amateur web developers. <br></p><ul class="compressed"><li>All development work is done on the production server;</li><li>No code is under source control;</li><li>FTP is the main file transfer development medium;</li><li>Most applications are coded in a home-brew, non-reusable manner;</li><li>Almost no quality control or testing.</li></ul><p>I always knew there had to be a better way. It's not that the way we had been doing things didn't work - it did.&nbsp; It's just that we could be doing things so much better.&nbsp; Working smarter, not harder.&nbsp; So when the other developer left and I got put in charge, I made sure we put in place the measures and structure to have a solid, organized and <i>professional</i> development department.</p><p>If you too want to stop being an amateur web developer, and work smarter, here are my top 10 things to do.<br></p><ol><li><b>Use Source Control</b><br>It doesn't matter if you're just one developer working by yourself on your own project - everyone can benefit from source control. It is, hands down, the easiest way to manage all of the various code revisions that you will encounter in your project. Not only can it help you track all of the changes over time you've made to your application, in the event that a new change goes awry or you accidentally delete a file (or twelve), source control makes it easy to revert to before your blunder. The current top choice for source control is <a href="http://subversion.tigris.org/" mce_href="http://subversion.tigris.org/">Subversion</a>, an open source package meant as a replacement to <a href="http://www.nongnu.org/cvs/" mce_href="http://www.nongnu.org/cvs/">CVS</a>.<br><br></li><li><b>Institute testing</b><br>Far too my times, amateur developers are eager to push their new product out the door before it's ready for the big time. It's a common mistake; one where your emotions and over eagerness will get the best of you. Often times, however, an extra 10 minutes of time with your product will help you find the larger and more obvious errors that your client <i>will</i> catch first.&nbsp; And if you want to get even better with your testing, look at <a href="http://en.wikipedia.org/wiki/Test-driven_development" mce_href="http://en.wikipedia.org/wiki/Test-driven_development">test driven development</a>.<br><br> </li><li><b>Stop developing on the live site!</b><br>Usually out of convenience, developers will build the site on the final production server. This starts out being a good idea, since you're building the site in its final resting place, but what happens when you need to add a new feature or fix an existing bug? You can't turn debugging on for the live site, nor can you really use dummy test data in the production database.<br><br>So what's the answer? Create a development cycle. Locally, replicate as best you can the live production environment. Give yourself a local development database &amp; installation of you web server. Then, once you've got that bit sorted out, create some process to deploy your code to the production server. I'd recommend either <a href="http://samba.anu.edu.au/rsync/" mce_href="http://samba.anu.edu.au/rsync/">rsync</a> or some other scripting language that just checks out a copy of the source from version control on the production server.<br><br> </li><li><b>Use a bug tracker</b><br>The key to writing great software is documentation. Not only does this include well documented and commented code, but also documentation of problems and issues that have been found and/or fixed. When the user of your product reports an error, document it. Save the exact email, write some notes about your initial ideas on the cause of the problem &amp; write down potential fixes. Then once you've found your bug and squashed it, you mark the issue as resolved and archive it. Next time something breaks or you want to know how you fixed a similar problem, you'll have it documented.<br><br> </li><li><b>Lean the command line</b><br>Good developers don't just use a text editor to develop, they utilize command line tools to work smarter. Creating files, interacting with the database, running scripts and checking error logs.&nbsp; All these things can be done quicker and easier in the terminal. If you don't currently use the terminal or have any experience using command line tools, it can be a little daunting to get started. But take it slow, do <a href="http://www.seomoz.org/blog/web-developers-command-line-tricks" mce_href="http://www.seomoz.org/blog/web-developers-command-line-tricks">a lot or reading</a> and you'll find yourself spending more and more time in a text-only world.<br><br> </li><li><b>Utilize better server tools</b><br>Between dealing with down time, performance issues and bugs, running a popular site can give you an ulcer some times. But it doesn't have to be that way. If you can think of a difficult and stressul situation to deal with, nine times out of yen there is a tool to help. Here are a couple of my favourite.<br><br>High server resources? Check out <a href="http://tildeslash.com/monit/" mce_href="http://tildeslash.com/monit/">Monit</a> or <a href="http://god.rubyforge.org/" mce_href="http://god.rubyforge.org/">God</a>. Both monitor your server, and if the CPU usage or memory has gotten too high, or Apache stops responding, it will email you with notification. It's very flexible, to the point of it being able to actually restart Apache or other services if things get too crazy. The little brother of Monit is <a href="http://www.montastic.com/" mce_href="http://www.montastic.com/">montastic</a>, which can monitor your server remotely. If Montastic tries to connect to your server returns anything other than the expected 200, you'll get an email.<br><br>The other really awesome piece of server software is <a href="http://www.gnu.org/software/rcs/" mce_href="http://www.gnu.org/software/rcs/">RCS</a>. It is like a stripped down version control system, meant to version control individual files. So if you're on your web server and making a bunch of changes to your vhosts.conf file for Apache, RCS will store each iteration of the file for you. Thus, if you mess something up or need to look back at a change you made a while ago, it's as easy as a few keystrokes.<br><br> </li><li><b>T</b><b>alk with other developers</b><br>A lot of web developers out there tend to operate in a bubble. They'll pick up some programming knowledge after reading a book on PHP or something, but then never, ever, move beyond that. They'll continue, often years at a time, programming and developing the exact same way as they always have. While it's perfectly acceptable to stick with what you know, this is a dangerous phenomenon. Languages improve, security holes are found and fixed, new tools and techniques are developed and mature.&nbsp; You need to keep up with the times.<br><br>The best way to do that?&nbsp; Talk to other developers. There are plenty of blogs, forums &amp; mailing lists that offer a wealth of knowledge. People discuss new technologies, bounce ideas off each other, ask for help and give feedback. It's a very creative and invigorating enviornment full of really smart people creating really great tools. Being part of their conversation, or even just listening to it, is one of the best things you can do.<br><br> </li><li><b>Utilize a web application framework</b><br>This is a simple, but often life changing realization. I know far to many web developers who still create client websites as one-off pieces, custom coded each time to their clients specifications. People...this is a waste of time! I can <i>guarantee</i> you that at least 80% of the coding you do is repetitive, and you'll be much better served utilizing a framework.<br><br>Web frameworks are libraries of code, usually in the Model/View/Controller (MVC) pattern, that offer you a solid base to build your application on. Database connections, templating, basic CRUD operation and much, much, much more is taken care of by the framework. All you have to concentrate on is the fun stuff: creating creative solutions to the clients unique problems.<br><br>There are plenty of frameworks out there, but personally I'm a fan of <a href="http://www.cakephp.org" mce_href="http://www.cakephp.org">CakePHP</a> for my PHP work, and obviously <a href="http://www.rubyonrails.org/" mce_href="http://www.rubyonrails.org/">Rails</a> for my Ruby work.<br><br> </li><li><b>Read, read, read</b><br>Never, ever, be satisfied with your level of knowledge. There is always more languages to learn and more technologies to master. If you've got a good gasp on PHP, see what Ruby has to offer. Spend some time getting more accustomed to some MYSQL functions. Pickup a book on XLST. Whatever. Just make sure that you're always learning and advancing. Not only will it help you become a better developer, but you'll have a diverse catalog of tools and techniques in your bag of tricks. You'll never know where one will come in handy.<br><br> </li><li><b>Become a jack of all trades</b><br>The days of "I'm <i>just</i> a design guy" are over. A lot of developers think that they should just concentrate on one language or one discipline, and then try to be the very best at that one thing. That works well if you want to be some DBA admin stuck in a back office somewhere in a mega insurance company. The real development and creating happens by people who are multidisciplinary. <br><br>Have a strong design <b>and</b> read and write PHP. Be a sysadmin who know how to troubleshoot Apache, but can also understand the product life cycle. There is no magic formula of talents that guarantee your success, but as long as you don't pigeonhole yourself in to one field you'll do just fine.</li></ol><p>Alright folks, you got everything you need to become a professional web developer. Go check out some of the items I linked to, read up on them, and start incorporating them in to your development cycle. The best way to get better is to learn by doing.</p> Fri, Nov 30th 2007, 10:45 PDT http://www.gluei.com/blog/view/3 The Difference Between Good Code and a Good App http://www.gluei.com/blog/view/4 <p>Over the past few days I've been armpit deep in the source files of <a href="http://www.wordpress.org" target="_blank" mce_href="http://www.wordpress.org">Wordpress</a>, one of the worlds most popular and customized pieces of blogging software. I've been reading documentation, examining the database &amp; navigating my way through the many PHP files of Wordpress - the end goal being a plugin which interfaces with <a href="http://www.pligg.com" target="_blank" mce_href="http://www.pligg.com">Pligg</a>, a popular open-source social media (read "Digg-style") piece of software.</p><p>Considering that Wordpress is 4 years old, has a half dozen full-time developers and has many high profile users, I was expecting to find some quality code underneath it all.&nbsp; When I did lift the hood, I was astonished as to what I found...</p><code class="source">$wpdb-&gt;query("UPDATE $wpdb-&gt;users SET user_activation_key = '$key' WHERE user_login = '$user_login'");<br>$message = __('Someone has asked to reset the password for the following site and username.') . "\r\n\r\n";<br>$message .= get_option('siteurl') . "\r\n\r\n";<br>$message .= sprintf(__('Username: %s'), $user_login) . "\r\n\r\n";<br>$message .= __('To reset your password visit the following address, otherwise just ignore this email and nothing will happen.') . "\r\n\r\n";<br>$message .= get_option('siteurl') . "/wp-login.php?action=rp&amp;key=$key\r\n";<br><br>if (FALSE == wp_mail($user_email, sprintf(__('[%s] Password Reset'), get_option('blogname')), $message)) {<br>&nbsp;&nbsp;&nbsp; die('&lt;p&gt;' . __('The e-mail could not be sent.') . "&lt;br /&gt;\n" . __('Possible reason: your host may have disabled the mail() function...') . '&lt;/p&gt;');<br>} else {<br>&nbsp;&nbsp;&nbsp; wp_redirect('wp-login.php?checkemail=confirm');<br>&nbsp;&nbsp;&nbsp; exit();<br>}</code><p>For you non-programmers out there, that piece of code processes a request to reset the password of a user's account. Any programmer who has more than a couple years experience knows the code is doing many things wrong: namely raw SQL and HTML email code interwoven with PHP. Now I understand that Wordpress was written from scratch, and forked from a codebase that was originally written before the MVC architecture was common practice, but <i>come on</i>! That code is horrible!</p><p>Yet the worst part, aside from all the bad syntax and complete disregard for an coding best-practices is the lack of any kind of code comments or documentation. Anywhere. I'd guess that maybe 10% of any of the functions in Wordpress have any sort of comments above them and probably only 5% of those shed any real light on what the function does. It's only been through my long history tinkering with PHP applications and liberal use of the grep utility that I've been able to make heads of tails about how Wordpress functions internally.</p><p>To be quite honest, Wordpress is probably in the bottom 10% of quality in terms of software source code that I've ever seen.</p><p>This begs the question, "If it sucks so much, why is it so popular?"</p><p>Well, it's because Wordpress does its public-facing things incredibly well. Themes, plugins, ease on install, UI, community, etc are all created in (I hate to say) beatufil and elegant ways.&nbsp; From initial install to creating your first blog post, the process for the end user is spot on.&nbsp; And thanks in simple easy to read code and great documentation, creating <a href="http://codex.wordpress.org/Templates" mce_href="http://codex.wordpress.org/Templates">themes</a> and <a href="http://codex.wordpress.org/Plugins" mce_href="http://codex.wordpress.org/Plugins">plugins</a> is simple and painless.</p><p>This is a prime example of why success in writing and selling software is contingent on the quality of the <i>user</i> experience, and not the quality of the code behind the user experience.&nbsp; Like Microsoft, Wordpress figured out that in order to have successful software, you don't need to write the best source code.&nbsp; Instead, you need to create the best and easiest customer experience. This is why Linux is hands down better software than anything Redmond will ever write, but it's still looking for that mainstream acceptance.&nbsp; The end user's experience using Linux is still a few generations behind the ease of use of Windows.</p><p>It's as if a car owner likes their car based solely on the fact that the interior looks nice and the car is easy to drive.&nbsp; Never mind the fact that the car could be powered by an engine from a 1930s lawnmower.&nbsp; As long as the user has a good experience, and the technology powering it "just works," they could care less to look under the hood. Which to me sounds idiotic.&nbsp; Even though you'll never have to deal with it, don't you want the best quality engine under your hood?&nbsp; I would.<br></p><p>The reason software can get away with a quality user experience, but crappy engine, is that as consumers go, 99.9% of them wouldn't know the difference between quality professional source code and something like Wordpress.&nbsp; It's not that they can't look under the hood - they can. They just don't know how to make heads or tails of the code once they do.</p><p>Unlike nearly every other kind of technlogy and engineering in the world, programming is all virtual.&nbsp; You can't feel software to see if it feels heavy or "well built."&nbsp; You can't examine the source code to see if it looks worn or needs replacing since, well, software never wears down.&nbsp; Once "it works," it works.</p><p>My point in all of this is why you should care.&nbsp; If the source code works, won't age or break down and my experience as an end-user is great, why do I care that the underlying code is awful?&nbsp; Because it makes moving in any direction from where you are that much harder.</p><p>Crappy code make it harder for the Wordpress team to develop and maintain the code base.&nbsp; Crappy code means less care is taken by developers to be effecient, making scaling for high-volume webistes harder.&nbsp; Crappy code makes it harder to upgrade to new versions of Wordpress.&nbsp; But most importantly, crappy code makes understanding and preventing security holes by the development team very hard.&nbsp; A problem that has bitten Wordpress in the butt a <a href="http://wordpress.org/development/2005/05/security-update/" target="_blank" mce_href="http://wordpress.org/development/2005/05/security-update/">few</a> <a href="http://wordpress.org/development/2007/03/upgrade-212/" target="_blank" mce_href="http://wordpress.org/development/2007/03/upgrade-212/">times</a> <a href="http://news.netcraft.com/archives/2004/09/30/security_holes_in_wordpress_blogging_tool.html" target="_blank" mce_href="http://news.netcraft.com/archives/2004/09/30/security_holes_in_wordpress_blogging_tool.html">before</a>.<br> </p><p>All in all, for moest people the things in the above paragraph won't matter.&nbsp; They'll install their blog on their web hosting and blog for 6-months and then get busy with other things.&nbsp; But if you're looking to use some open source software like Wordpress for your next website, consider looking beyond the user-facing functionality and see what lies beneath the hood.</p> Wed, Jan 2nd 2008, 01:11 PDT http://www.gluei.com/blog/view/4 Using Your rsync.net Account as a SVN Repository http://www.gluei.com/blog/view/5 <p>The guys over at <a href="http://www.rsync.net" target="_blank" mce_href="http://www.rsync.net">rsync.net</a> do a fantastic job.&nbsp; For literally a few dollars a month, you have a remote file system that serves as a great backup, file host &amp; now as a <a href="http://subversion.tigris.org/" target="_blank" mce_href="http://subversion.tigris.org/">SVN</a> repository.&nbsp; rsync.net gives you some very basic instructions on how to do this...</p><blockquote><p>Yes. The svnserve command is available for you to run, remotely, over<br /> SSH. This means that you can upload a repository with rsync or sftp and<br /> then<br /> access it remotely with any tool that supports the <code>svn+ssh://</code> URL<br /> format.</p></blockquote><p>This is pretty straight forward, but I'll save you some headaches and help you get up and running.</p><p>To get started, use <code>svnadmin</code> to locally make a svn repo on your machine.</p><br /> <br /> <p><br /> <code class="source">svnadmin create myrepo</code></p><br /> <br /> <p>Now, SSH in to your rsync.net account to start <a href="http://svnbook.red-bean.com/en/1.0/ch06s03.html" target="_blank" mce_href="http://svnbook.red-bean.com/en/1.0/ch06s03.html">svnserve</a>.&nbsp; <i>Note: that you'll have to change your username and host to yours from your rsync.net account.</i></p><br /> <br /> <p><br /> <code class="source">ssh 8058@usw-s008.rsync.net svnserve -d</code></p><br /> <br /> <p>The <code>-d</code> part starts svnserve in "daemon mode."&nbsp; Checkout <code>svnserve --help</code> for more options.</p><p>Now you'll need to <code>rsync</code> your local repo to the remote folder you want to house it.&nbsp; In my case, all my repos are in the "svn" folder off my home. </p><br /> <br /> <p><br /> <code class="source">rsync -avz myrepo 8058@usw-s008.rsync.net:svn/</code></p><br /> <br /> <p>The <code>-a</code> tells rsync to operate in "archive mode," which basically says you want to recursivly transfer and preserve most everything.&nbsp; The <code>-v</code> speficies verbose output and the <code>-z</code> specifies the transfer should use compression.&nbsp;</p><p>So now your repo is located remotely on your rsync.net host.&nbsp; Here's the magic command to access it.</p><br /> <br /> <p><br /> <code class="source">svn co svn+ssh://8058@usw-s008.rsync.net/data2/home/8058/svn/myrepo localfolder</code></p><br /> <br /> <p>Please note the following...</p><ol><li>SVN is using the svn+ssh protocal</li><li>Username 8058 at the beginning of the address</li><li>The <code>data2/home/8058</code> to access my repository on the file server.&nbsp; I got this by running the <code>pwd</code> command.&nbsp; Using <code>...s008.rsync.net/svn/myrepo</code> will not work. </li></ol><p>If you did everything correctly, you should be able to checkout just fine.&nbsp; If you have any questions, feel free to <a href="/contact" mce_href="/contact">shoot me an email.</a></p> Fri, Jan 4th 2008, 01:25 PDT http://www.gluei.com/blog/view/5 Welcome to GLUEinteractive http://www.gluei.com/blog/view/1 <p>Hello, and welcome to GLUEineractive! Today we're blowing the doors off this place, letting everyone catch a glimpse of who we are and what we have to offer. </p><br /> <br /> <p>GLUEineractive is a different kind of web-design firm. We pride ourselves on taking a complete, holistic approach to creating your website. While many other companies fall short by exclusively offering design or development services, GLUEinerative has the skills to support you through the entire process of creating your website — front to back.</p><p>Therefore, we're able to provide you with the following <a href="/services" mce_href="/services">services</a>:</p><ul><li>Web design and development</li><li>Brand Identity</li><li>Content Development and Editing</li><li>Information Architecture</li><li>Web Technology Consulting</li><li>Usibility Consulting</li><li>Online Media Relations &amp; Development</li></ul><p>If you're interested in having us help you with your website, feel free to <a href="http://www.gluei.com/contact" title="Contact GLUEinteractive" target="_blank" mce_href="http://www.gluei.com/contact">drop us a line</a>.</p><p>As for this blog - well, it's going to delve into the multi-faceted world of web communications. Aside from news and information about the service wing of GLUEinteractive, this blog will also cover topics such as the <a href="http://www.cakephp.org" target="_blank" mce_href="http://www.cakephp.org">CakePHP framework</a>, news on <a href="http://www.tuneshout.com" target="_blank" mce_href="http://www.tuneshout.com">our side project TuneShout</a>, online media relations, brand and content development, internet business and the online music industry.</p><p>So bookmark us, or subscribe to our RSS feed &amp; keep up to date with the ever-evolving world of the web. See you back here soon! </p> Mon, Sep 17th 2007, 00:49 PDT http://www.gluei.com/blog/view/1