Sunday, January 31, 2010

Bootstrapping Zend Framework Applications

See Bootstrapping Zend Framework Applications at its new home on bradley-holt.com.

In my previous post I talked about how the Front Controller pattern is implemented in Zend Framework. We saw how every application request can go through the public/index.php script. Everything that your application does is then eventually called from either the bootstrap() or run() method in Zend_Application.

One of the constructor arguments passed to Zend_Application specified the configuration file to use. In the case of the demo blogging application, Postr, you'll see that the configuration file used is application/configs/application.ini. If you look at this configuration file you'll see that there are four sections: production, staging, testing, and development. The staging, testing, and development sections all inherit from production meaning that they will inherit all of its settings, unless overridden (as is the case, for example, with the phpSettings.display_errors setting in testing and development).

The other constructor argument passed to Zend_Application specified the application's environment. For those paying close attention, the environment was actually the first argument and the configuration file was the second argument passed to the constructor of Zend_Application. By default, the demo application is set to run in development mode. This means that the development section from application/configs/application.ini will be used. Remember, development inherits from production so any settings not explicitly overridden from production would be inherited and used.

There's quite a bit that can be setup in the configuration file. However, some things may be easier to (or only possible to) setup programmatically. This is where application/Bootstrap.php comes in. In your Bootstrap class you can write initializers for various parts of your application. These methods should be protected and their names should begin with _init. Let's look at the initializers I've written in the demo application:

  • _initViewHeadTitle() first makes sure that the "view" resource has been bootstrapped and then gets this resource, which we happen to know is an object of type Zend_View_Abstract. We then set the separator used by the HeadTitle view helper to " :: ". This means that each head title appended or prependend will be separated by this string. Next, a title of "Postr" is prepended so that this title will be used on every page.
  • _initPagination() simply sets the partial view script to be used by Zend_Paginator (I plan on further explaining Zend_Paginator in another blog post).
  • _initNavigation() sets up our navigation structure using Zend_Navigation (I plan on further explaining Zend_Navigation in another blog post as well).

In my next post in this series I plan on taking a look at the Model-View-Controller pattern in Zend Framework.

Friday, January 29, 2010

Front Controller Pattern in Zend Framework

See Front Controller Pattern in Zend Framework at its new home on bradley-holt.com.

I recently gave a Zend Framework Introduction presentation at our local PHP Users Group. I built a demo blogging application called Postr that I used as an example throughout the presentation. There was way too much material to cover in the time available so I plan on writing a series of blog posts, each covering a specific area of Zend Framework. Here is the first (and hopefully not the last!) post in this series based on the presentation and demo application.

Like many other frameworks, Zend Framework provides an implementation of the Front Controller pattern. This means that all HTTP requests can be sent through a centralized point. This allows you to take advantage of Zend Framework's routing and Model-View-Controller (MVC) components, if you so choose. By default this is the public/index.php file (click to see the source code). Note that in Zend Framework only the public directory is accessible to website visitors, all of your other directories should be outside of your document root. You'll see several things happening in the public/index.php script:

  1. The APPLICATION_PATH constant is defined. This is the full path to the application directory. You'll see this constant used later.
  2. The APPLICATION_ENV constant is defined. This will typically be either production, staging, testing, or development. This will be used to determine which configuration section to use.
  3. The library directory is added to the include path. This is so that the Zend library code (if you decide to place it in your library directory) or any other libraries used can be found.
  4. A new instance of Zend_Application is created. Two arguments are passed to its constructor: the application environment (defined in 2) and the location of the configuration file. Typically this is application/configs/application.ini. The application path (defined in 1) is used to provide the absolute path to the configuration file.
  5. The application is then bootstrapped and run. It may seem odd to those used to writing PHP scripts, but everything that happens in your application is subsequently called from either the bootstrap() or run() method in Zend_Application. In fact, this is the essence of the Front Controller pattern.

By itself, public/index.php can't make sure that all HTTP requests go through it. If you're using Apache as your web server then you can use its rewrite module to do this (other web servers have equivalent functionality). This is typically done in public/.htaccess. There are several things happening in this file:

  1. First the application environment is set so the application knows if it's running in production, staging, testing, or development mode.
  2. In the demo application, I set the default character set to utf-8.
  3. Some environments require you to set a rewrite base. If needed, this is usually the first part of the URI (e.g. just / if your application is the only thing on the web server or /postr/ if your application is in a subdirectory named "postr").
  4. Turn on the rewrite engine.
  5. Don't rewrite if the requested file is a regular file with size greater than zero, is a symbolic link, or is a directory. This way static files such as images, CSS files, and JavaScript files aren't rewritten.
  6. Otherwise, rewrite the request to index.php.

In my next post in this series I plan on taking a look at what happens during the bootstrapping phase of your Zend Framework application.

Zend Framework Introduction

See Zend Framework Introduction at its new home on bradley-holt.com.

Slides from last night's Zend Framework Introduction at the Burlington, Vermont PHP Users Group are now available online:

The presentation is available under a Creative Commons license.

As I mentioned earlier, there's also a demo blogging application called Postr available on GitHub. The application is available under a free/open source New BSD License so feel free to use, redistribute, and/or modify it however you'd like.

Thursday, January 28, 2010

Learn Zend Framework

See Learn Zend Framework at its new home on bradley-holt.com.

At tonight's (Thursday, January 28, 2010) Burlington, Vermont PHP Users Group meeting I'll be giving a Zend Framework Introduction presentation. I'll be covering how to use several features of Zend Framework and common patterns including:

I've created a demo blogging application called Postr that I'll be using as an example throughout the presentation. Thanks to Jason there is some CSS that makes the application much more usable. I will post the presentation to my SlideShare account after tonight's meeting.

The meeting is from 6:00 PM - 8:00 PM at Office Squared in Burlington, Vermont. If you're in the area and interested in attending then you can register for free on Eventbrite.

Wednesday, January 20, 2010

Open Source and Open Standards Bill

See Open Source and Open Standards Bill at its new home on bradley-holt.com.

The other day there was a discussion on the VAGUE mailing list about an open source and open standards bill (H.516) [PDF] recently introduced in the Vermont General Assembly (a.k.a. legislature). It's technically an amendment to an existing act and has the following stated purpose:

This bill proposes to require the department of information and innovation to advise against the acquisition by a state agency of proprietary software or software that operates by means of proprietary protocols when acceptable functionality can be achieved with open source software and open standard protocols and to ensure that the expected total life-cycle costs of software are fully evaluated prior to acquisition.

Overall I see this as a positive move for the State of Vermont. It does not seem to put the requirement for open source and open standards ahead of the particular business needs at hand since it only "advise[s] against the acquisition by a state agency of proprietary software or software that operates by means of proprietary protocols when acceptable functionality can be achieved with open source software and open standard protocols." However, Mitch Lieberman points out:

@BradleyHolt functionality does not directly = biz value IMHO, biz value needs to include ROI of functions, thus includes TCO

I agree with Mitch that the bill could do a better job of addressing not just functionality, but also return on investment (ROI) and total cost of ownership (TCO). These should be the primary considerations of any responsible organization in deciding what software to use. However, since it is the public's money being used to purchase this software it is worth considering whether our resources are being used to further entrench proprietary software and standards, or whether we are instead enriching the public commons by supporting open source software and open standards.

In addition to the above, there are some details of the bill that demonstrate some possible misunderstandings of how open source software works. While it's not anywhere in its text, the bill is described as being "An act relating to comparing the costs and benefits of downloading free open source software with purchasing proprietary computer software." There are a couple of misconceptions in this one statement. First, cost should not always be the primary motivation behind using open source software: the freedoms it gives you are just as important. In fact, not all proprietary software costs money and not all open source software is available free of charge. Second, "downloading" is simply a means of distributing software. Proprietary software can often be downloaded. Open source software is sometimes distributed on a physical medium.

It's not stated explicitly in the bill, but people sometimes think that if they release their own software under an open source license they are somehow giving up control of the licensed software project. While there are many benefits of giving up control (which are outside the scope of this blog post), it's worth noting that you don't have to. When you license your software you still own the copyright on that software. You can still do whatever you want with that software, including release it under a different license later. Once you accept outside contributions then you need to honor whatever license has been given to you be your contributors (unless they agree to transfer copyright to you, but this can be tricky). It's your choice whether or not to accept those contributions in the first place. You are still completely in control (as long as you want to be) and have simply given others the possibility of benefiting from your work.

Monday, January 11, 2010

Zend Framework Route Context Plugin

See Zend Framework Route Context Plugin at its new home on bradley-holt.com.

I want to share a simple, yet very useful, custom Zend Framework plugin that we use on almost all of our projects. The plugin (and associated code in the layout file) provides the Zend Framework route context as CSS classes on the body element. This allows us to change the design (using CSS) and/or behavior (using unobtrusive JavaScript) on the page based on the Zend Framework route. For example if the module name was default, the controller name was news, and the action was get then the opening of the body element would like this:

<body class="default news get">

There are some limitations. For example, you need to be careful not to overlap module, controller, or action names. If this is a problem for you then you could preface the class names (e.g. module-default, controller-news, action-get).

The RouteContext plugin hooks into the preDispatch event and creates an array of route context strings. This example simply uses the module, controller, and action names as the route context. Often I'll add other contextual strings to this array as needed. This array is then assigned to the view. The layout view script then simply implodes this array into the value of the class attribute using a space character as the glue.

Sunday, January 10, 2010

Phing Build Script

See Phing Build Script at its new home on bradley-holt.com.

I've been experimenting with using Phing to automate building and deploying web applications. I want to share one of my build scripts and perhaps get some feedback from anyone with more experience using Phing. The requirements for the build script are fairly simple:

  • It will not handle deployment. This particular web application is deployed by the client's IT department.
  • It will create a ZIP file (it could just as easily create a tar.gz file) that the client's IT department can extract and deploy.
  • It will rename the document root since the document root is a different directory name in the client's production environment then it is in our development and testing environments.

Next, an outline of what the build does:

  1. Prompt for Subversion credentials (I'd rather not store these in a file).
  2. Prompt for the Subversion tag to build from.
  3. Delete the source directory if it exists.
  4. Export the given tag to the source directory.
  5. Rename the document root.
  6. Create a ZIP file, named after the version, of the source directory's contents.
  7. Clean up after itself by deleting the source directory.

Both of the build files are in the project's root directory (in my project, this is one directory above the document root). The build.properties file defines three properties: document root (so we can rename it to this new name), the source directory (the place to export to and then manipulate folders/files), and the URL to the repository's tags directory.

The build.xml file is the actual build script, performing the actions outlined above. I've obfuscated the project name to be "acme". I could not find a way to create a prompt that hides the Subversion password as it is entered (anyone?). For renaming the document root, I used the exec task to execute a move (mv) command since the move task failed for me (so this script will not work as-is on Windows).

Executing this script is as easy as running phing build-tag (once Phing is installed) from within the project's root directory. Please let me know if you have any questions or see any room for improvement.

Thursday, January 7, 2010

Marketing Is Not Dead

See Marketing Is Not Dead at its new home on bradley-holt.com.

Forrester Research claims that 2010 is the year marketing dies. I mostly agree with the article and its conclusions. However, I do not think that marketing is dead: I just do not think it means what you think it means. The article conflates three distinct concepts: marketing, media, and advertising (although media, advertising, and public relations do overlap). It assumes that media exists to serve advertising and that advertising in turn exists to serve marketing. The second part (advertising serving marketing) is fairly accurate since advertising is a marketing tactic. The first part has mostly been true in the past (media serving advertising). I think it would have been more accurate to say that 2010 is the year we decouple marketing from advertising and advertising from media.

The cost of producing and distributing media has become much cheaper in the digital world. It is no longer assumed that media cannot be produced or distributed without advertisers footing the bill. The decoupling of media from advertising has opened up the door for all sorts of creativity (and arguably a lot of garbage, too). Public, educational, and governmental media have been producing and distributing content free from advertising for years.

On the flip side, it is no longer assumed that marketers need to spend a lot of money on advertising to get their messages in front of eyeballs (or ears or whatever). If you have a good message then people can hear that message without the need for paid media gatekeepers. Word-of-mouth has long been an effective marketing technique which requires no media buys. With the Internet, Web 2.0, social media, or whatever you want to call it today word-of-mouth marketing takes on a whole new dimension.

Sure, if you have a product or message that does not resonate with people then you may still need old media and advertising to get your product and message in front of them. Of course, once people try your product and are disappointed with it they will share their thoughts about your product with other people. I hope that 2010 is the year that old media and advertising wanes and that good old word-of-mouth has a resurgence in influence. This is the kind of marketing we focus on at Found Line: marketing as a form of communication and education. As the Forrester Research post concluded, "Marketing is dead. Long live marketing!"

Wednesday, January 6, 2010

TEK·X PHP Conference

See TEK·X PHP Conference at its new home on bradley-holt.com.

I registered today for the upcoming TEK·X PHP conference in Chicago. I attended both ZendCon '08 and '09 but this will be my first TEK·X experience. I have heard that TEK·X is more of a community conference while ZendCon has a reputation for being more corporate. The schedule has not been announced yet (which is why I was able to get my ticket for 35% off). However, several people who have seen the schedule have said that there are some excellent sessions lined up. This year they are replacing the Unconference with a Hack Track which sounds like a lot of fun (even though I am a big fan of unconferences). Hope to see you there!

Saturday, January 2, 2010

Web Design and Web Development

See Web Design and Web Development at its new home on bradley-holt.com.

Back in October, Jeffrey Zeldman tweeted something that I strongly agree with:

Real web designers write code. Always have, always will. #aea

This sparked many conversations including these two tweets from Chris Shiflett:

According to @zeldman, real web designers write code. (I think he means HTML and CSS, not PHP, Perl, and Python.) What do you think?

I’ve now asked, separately, whether developers and designers should know HTML and CSS. In both cases, most think they should. Interesting.

To which I responded (brackets added):

@shiflett IMHO, the demarcation between web developers and web designers should be POSH [Plain Old Semantic HTML]. That's what both need to know.

I have a pretty strong opinion about this. You could say that I have the luxury of working with an excellent designer who implements all of his own CSS—even tackling much of the JavaScript coding on websites we build. To be clear: he is a designer, not a developer—working in both print (which is more technical than you might think) and web.

The typical process is summarized well in Marco Tabini's PHP Advent 2009 post on CSS and Other People:

From a developer’s perspective, “design work” means having to deal with the often hated, sometimes impossible, and always challenging task of translating a designer’s comp into a combination of HTML and CSS that will render properly on browsers that are often at complete odds with one another.

In my opinion, that process is broken. Why is it assumed that because HTML and CSS are "code" it should be a developer's job to implement these? Any decent designer is already familiar with the concept of separating presentation and content with style sheets (which are supported in Adobe InDesign, QuarkXPress, and even PageMaker and Microsoft Word). Is learning HTML and CSS, both declarative languages, considered too hard for designers?

Let's take a look at comps and the dreaded "s" word—slicing. As Marco pointed out, trying to "slice" a comp into HTML and CSS is "sometimes impossible" and "always challenging." If a designer is only providing a comp, and not the HTML and CSS, it is very likely that the designer does not have a solid understanding of things like progressive enhancement, browser compatibility, and even what is possible on the web.

The use of a comp generally assumes that design is purely visual and that all representations of the web page should look exactly like the comp. How should the content be presented to screen readers, to mobile devices, and in print? Sure, you could provide comps for each of these scenarios but this is not scalable and you quickly risk violating the "One Web" concept. Thinking of a web page through the lens of only one specific visual representation of that page is very limiting.

Do you agree that the typical process is broken? If so, what are the barriers to fixing this process? Do we need better trained web designers? Do organizations need to be educated on how to better structure their web teams? This problem will eventually self-correct. My prediction is that teams with web designers that know HTML and CSS will create better websites and web applications and be more successful than teams using the old process.

Friday, January 1, 2010

Year In Review

See Year In Review at its new home on bradley-holt.com.

Being the first day of 2010, I thought it would be a good time to take a look back at 2009…

Burlington, VT PHP Users Group

2009 was the second full year of the Burlington, VT PHP Users Group. We had some fun meetings and presentations including:

January
Jason Pelletier gave a presentation on CSS for Developers.
February
Aaron Carlino demonstrated SilverStripe, an open source CMS/framework built in PHP.
March
Special guest Paul Reinheimer gave a presentation called "Easy Problems are the Hard Problems" taking an in-depth look at the easy/hard parts of building web applications.
April
Rob Riggen gave a talk on website performance optimization.
May
Rene Churchill gave a presentation on MySQL database optimization.
July
Matthew Weier O'Phinney gave his Play-Doh: Modelling Your Objects presentation.
August
Matthew Weier O'Phinney presented again in August, this time giving a hands-on unit testing crash course [ODP].
September
September's meeting was a casual get-together instead of a formal meeting and presentation—a change of pace from the typical meeting format.
October
I gave a talk geared towards PHP beginners.
November
November's meeting fell on one of Zend Framework's Bug Hunt Days. Held monthly, Bug Hunt Days are designed to encourage the community to help triage and resolve issues in the framework. Matthew Weier O'Phinney guided us through effective bug reporting and taught us how to contribute patches. As part of Bug Hunt Days, my first Zend Framework patch was accepted, a small addition to the documentation.
December
December marked the second birthday of our local PHP Users Group and that month's meeting turned out to be a fun social event.

Our users group also won a free pass to ZendCon '09, and Jase Roberts was the lucky recipient. He joined fellow Vermonters Matthew Weier O'Phinney, John Valance, and me at the annual PHP conference.

The Browser

Jonathan Butler started a program on our local community radio station called The Browser. It's "a show about the people who bring the world wide web to [Burlington, VT]." Jason and I were on the show twice—once in February and again in August.

Town Meeting Day Vermont, ACM-NE, and Tagnabit

The first Tuesday of March was Town Meeting Day here in Vermont. Citizens throughout Vermont gathered together to elect local officers and vote on budgets. As an experiment we put together a website, tmdvt.net/09, to aggregate content from social media sites around Town Meeting Day Vermont '09. If you used the appropriate tags in your tweets, Flickr uploads, blog posts (if indexed by Technorati), YouTube uploads, and bookmarks on Delicious, then your content showed up on the website. I wrote a post recapping some things we learned from the experiment.

As a result of that project, Bill Simmon and Seth Mobley from Vermont Community Access Media (VCAM) approached us about doing something similar for the Alliance for Community Media Northeast Region (ACM-NE) conference they were organizing here in Burlington, VT. We built acmne.net/09 for the conference and it was a big hit. I spoke on a social media panel (which Liz Schlegel moderated) and helped with a social media workshop at the conference. Colin Rhinesmith, who was on the panel with me and also helped with the workshop, posted a good summary of the conference on his blog.

We then took the idea from Town Meeting Day Vermont and ACM-NE a step further, creating Tagnabit—aggregating tweets, photos, blog posts, videos, and bookmarks for any arbitrary tag. Bill Simmon wrote a good blog post on how Tagnabit could be used.

Jelly/Coworking

I was excited to see Jen Mincar open up a coworking space, Office Squared (o²), here in Burlington, VT in 2009. I think it will help bring more cohesiveness to the local technology community since many of her customers work in technology-related industries. As a precursor to its opening, we hosted a Jelly at Found Line in July, inviting entrepreneurs and freelancers to work in our studio for an afternoon. Here are some photos from the Jelly and another one at the Burlington Free Press.

Vermont Code Camp

September saw the first ever Vermont Code Camp, bringing together people from local technology communities around .NET, PHP, Ruby, and Python. The event was a huge success with 85 attendees and 19 sessions. I had a small part in organizing the event but the real credit goes to Rob Hale, Julie Lerman, and everyone else who organized, volunteered, and presented. I also gave a presentation on Resource-Oriented Web Services as part of the code camp.

ZendCon

ZendCon is the biggest conference of the PHP community, and this year's event was my second ZendCon. What can I say? The talks were excellent. The people were even better. I ended up co-presenting at the UnCon with Michelangelo van Dam and Anna Filina on the role of a PHP user group.

Moving On

2009 seemed to be the year for people in the PHP community to change jobs. Following that trend, I made the move to Found Line full time last month, leaving Vermont Oxford Network. As I said before I'm very happy to have more time to focus on our clients' projects and to work with free/open source software and open standards full time.

Work

2009 was a busy year. Some of the work included:

Phew—a lot to say! I hope you had a good 2009, and have an even better 2010.