<?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>P'unk Avenue Window &#187; Apostrophe</title>
	<atom:link href="http://window.punkave.com/category/apostrophe/feed/" rel="self" type="application/rss+xml" />
	<link>http://window.punkave.com</link>
	<description></description>
	<lastBuildDate>Sat, 24 Jul 2010 01:15:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Symfony 2 hub-bub</title>
		<link>http://window.punkave.com/2010/06/10/symfony-hub-bub/</link>
		<comments>http://window.punkave.com/2010/06/10/symfony-hub-bub/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 19:01:25 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1169</guid>
		<description><![CDATA[Symfony is the best framework for building web applications in PHP. The forthcoming Symfony 2 is a dramatic improvement and a complete rewrite with many new features and, even more importantly, better software architecture. Enthusiasts may have heard about the State of Symfony 2 Online Conference to be held on June 23rd. Fabien and the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.symfony-project.org/">Symfony</a> is the best framework for building web applications in PHP. The forthcoming Symfony 2 is a <a href="http://www.symfony-reloaded.org/">dramatic improvement and a complete rewrite with many new features</a> and, even more importantly, better software architecture. Enthusiasts may have heard about the <a href="http://www.symfony-live.com/">State of Symfony 2 Online Conference</a> to be held on June 23rd. Fabien and the Sensio team have encouraged folks to become &#8220;Symfony conference hubs&#8221; and invite others to attend the conference from our offices and enjoy the benefits of our lovely projector, coffee, etc. And P&#8217;unk Avenue is definitely all about it. Please RSVP by commenting here. </p>
<p>WHAT: Symfony 2 Live Conference<br />
WHERE: P&#8217;unk Avenue offices, 1168 E. Passyunk Ave, Philadelphia PA<br />
WHEN: 11am Wednesday, June 23rd</p>
<p>Thanks to our hub status, <b>You do not have to buy your own Symfony 2 ticket</b> to attend at our office.</p>
<p>We&#8217;re looking forward to discussion and possibly busting out the Symfony 2 sandbox and experimenting after the conference.</p>
<hr />
Amid the excitement about Symfony 2, this would be a good time to mention our ongoing support for Symfony 1.4, and by extension Apostrophe 1.x. If Symfony 2.0 is coming, does that mean we&#8217;re going to abandon Symfony 1.x and Apostrophe 1.x?</p>
<p>No, not by a long shot, not any time soon. Symfony 2 will not be backwards compatible in a &#8220;super easy upgrade path&#8221; way, which is a valid choice to make improvements that would otherwise be impossible but an obvious problem for existing projects. And we have plenty of those. What&#8217;s more, Symfony 2 requires PHP 5.3.x at a minimum, and we know how tough it can be to move clients along just to PHP 5.2.x. </p>
<p>Fortunately, Sensio had the wisdom to make Symfony 1.4 a long-term-support release. And since Apostrophe 1.x is happily married to Symfony 1.4, that means we&#8217;re all in good shape.</p>
<p>Symfony 1.4 is supported until November of 2012, and Apostrophe 1.x will also be supported until at least November of 2012. </p>
<p>At some point, Apostrophe 2.x will come into being and it will be based on Symfony 2, but we have many client and internal projects that are purring away happily on Symfony 1.4 and we have absolutely no interest in abandoning it. So you can very safely pursue client projects based on the current stable releases of Apostrophe.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/06/10/symfony-hub-bub/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Introducing Apostrophe&#8217;s Blog Plugin</title>
		<link>http://window.punkave.com/2010/06/07/introducing-apostrophes-blog-plugin/</link>
		<comments>http://window.punkave.com/2010/06/07/introducing-apostrophes-blog-plugin/#comments</comments>
		<pubDate>Mon, 07 Jun 2010 14:07:48 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1161</guid>
		<description><![CDATA[Apostrophe, our content management system, now sports a nifty new blog plugin. And you can see it in action on GPTMC&#8217;s Philly360.
Wondering where the blog is? In the context of a larger website, a blog doesn&#8217;t always jump out and shake you by the lapels. On philly360 it&#8217;s the engine behind The Insider:



Notice the navigation [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.apostrophenow.com/">Apostrophe</a>, our content management system, now sports a nifty new blog plugin. And you can see it in action on GPTMC&#8217;s <a href="http://philly360.visitphilly.com/">Philly360</a>.</p>
<p>Wondering where the blog is? In the context of a larger website, a blog doesn&#8217;t always jump out and shake you by the lapels. On philly360 it&#8217;s the engine behind <a href="http://philly360.visitphilly.com/the-insider">The Insider</a>:</p>
<hr />
<a href="http://www.flickr.com/photos/punkavenue/4678235935/" title="Screen shot 2010-06-07 at 9.19.17 AM by P'unk Ave, on Flickr"><img src="http://farm5.static.flickr.com/4057/4678235935_274cbc930c.jpg" width="500" height="408" alt="Screen shot 2010-06-07 at 9.19.17 AM" /></a></p>
<hr />
<p>Notice the navigation links at the left. You can spelunk by category, date or tag. </p>
<p>Don&#8217;t see the categories? That&#8217;s because, on this particular site, they have been rebranded as &#8220;Features.&#8221; This is a common way to use Apostrophe blog categories: as separate &#8220;blogs.&#8221; It&#8217;s possible to set them up with entirely separate pages at any point in the site or, as in this case, as subpages of the main blog.</p>
<p>The Apostrophe blog plugin also drives the <a href="http://philly360.visitphilly.com/events">Events page</a>:</p>
<hr />
<a href="http://www.flickr.com/photos/punkavenue/4678866010/" title="Screen shot 2010-06-07 at 9.23.19 AM by P'unk Ave, on Flickr"><img src="http://farm2.static.flickr.com/1299/4678866010_6a02f2ff82.jpg" width="500" height="323" alt="Screen shot 2010-06-07 at 9.23.19 AM" /></a></p>
<hr />
<p>But that&#8217;s not quite the whole story. In truth, the blog is front and center on the <a href="http://philly360.visitphilly.com/">home page</a>. Let&#8217;s take another look:</p>
<hr />
<a href="http://www.flickr.com/photos/punkavenue/4678865960/" title="Screen shot 2010-06-07 at 9.22.56 AM by P'unk Ave, on Flickr"><img src="http://farm5.static.flickr.com/4048/4678865960_80334ff66f.jpg" width="500" height="411" alt="Screen shot 2010-06-07 at 9.22.56 AM" /></a></p>
<hr />
<p>Notice the &#8220;News&#8221; and &#8220;Events&#8221; sections. These are Apostrophe slots pulling in recent blog posts and recent events from the blog plugin. Editors can plug in recent posts and events, or plug specific posts and events into specific pages. And designers can customize the presentation of posts to suit any page template.</p>
<p>Visitors can comment on blog posts in a spam-free environment, optionally logging in via Facebook, Twitter and several other services thanks to the excellent <a href="http://www.disqus.com/">Disqus</a> blog comment management service.</p>
<p>All of these capabilities are standard in Apostrophe&#8217;s blog plugin. And it&#8217;s open source, so <a href="http://www.symfony-project.org/">Symfony</a> developers can dive right in. Visit the <a href="http://trac.apostrophenow.org/wiki/ManualOverview">Apostrophe documentation</a> for details.</p>
<p><i>&#8220;Great, so how come your own blog is still running WordPress?&#8221;</i> That will change! It&#8217;s not broken and we have plenty of client projects to build, so it&#8217;s not our first priority today. But our blog will be migrating to punkave.com/window. We need to take a little time to design it nicely and take advantage of Disqus&#8217; &#8220;import comments from Wordpress&#8221; feature.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/06/07/introducing-apostrophes-blog-plugin/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Open Source Help Desk</title>
		<link>http://window.punkave.com/2010/04/14/open-source-help-desk/</link>
		<comments>http://window.punkave.com/2010/04/14/open-source-help-desk/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 14:00:15 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Symfony]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1103</guid>
		<description><![CDATA[TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;
CALLER: &#8220;I chose your open source project for my client project and it&#8217;s due tomorrow and it doesn&#8217;t work! This is your problem and you must fix it immediately or I will explode!&#8221;
TOM: [CLICK]

TOM: &#8220;Open source help desk, this is Tom [...]]]></description>
			<content:encoded><![CDATA[<p>TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;I chose your open source project for my client project and it&#8217;s due tomorrow and it doesn&#8217;t work! This is your problem and you must fix it immediately or I will explode!&#8221;</p>
<p>TOM: [CLICK]</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;Your code has several bugs, which I am going to describe in harsh and unsympathetic but highly accurate detail.&#8221;</p>
<p>TOM: [Hangs up on caller, then fixes those bugs]</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;I translated your program into Swahili! Here&#8217;s the XLIFF file. Also I found a bug. Here&#8217;s a patch file.&#8221;</p>
<p>TOM: &#8220;Yay! Welcome to the cool people&#8217;s club! We&#8217;re having chocolate ice cream. Would you like some?&#8221;</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;500 ERROR! AAAAAAAAAAAAAA!&#8221;</p>
<p>TOM: &#8220;Lower your voice, read your log files, try the dev controller and call back.&#8221;</p>
<p>CALLER: [reads own log files, discovers glaringly obvious permissions problem, solves it, is never heard from again]</p>
<hr />
TOM: &#8220;Open source help desk, this is Tom speaking. How may we help each other?&#8221;</p>
<p>CALLER: &#8220;something isn&#8217;t quite right. When I do X, Y and Z, I get the following error message [copies and pastes complete error message].&#8221;</p>
<p>TOM: &#8220;reproducible bug reports make me deeply happy. I&#8217;ve just committed a fix in svn. Would you like some ice cream?&#8221;</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/04/14/open-source-help-desk/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apostrophe Speaks Your Language</title>
		<link>http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/</link>
		<comments>http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/#comments</comments>
		<pubDate>Thu, 25 Mar 2010 00:18:52 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[symfony]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1076</guid>
		<description><![CDATA[
We&#8217;ve just released version 1.0.9 of Apostrophe, our content management system. This is an exciting release because it includes French, German and Spanish user interfaces, as well as improved support for translating the actual content of your site into multiple languages.
If you visit our demo site and switch languages you&#8217;ll see pages with pretty translated [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/screen-shot-2010-03-24-at-8-13-52-pm/" rel="attachment wp-att-1077"><img src="http://window.punkave.com/wp-content/uploads/2010/03/Screen-shot-2010-03-24-at-8.13.52-PM.png" alt="Apostrophe en francais" title="Apostrophe en francais" width="377" height="218" class="alignnone size-full wp-image-1077" /></a><br />
We&#8217;ve just released version 1.0.9 of <a href="http://www.apostrophenow.com/">Apostrophe</a>, our content management system. This is an exciting release because it includes French, German and Spanish user interfaces, as well as improved support for translating the actual content of your site into multiple languages.</p>
<p>If you <a href="http://demo.apostrophenow.com/">visit our demo site</a> and switch languages you&#8217;ll see pages with pretty translated chrome but no content. That, of course, is because our own demonstration web site&#8217;s content is currently only available in English. Feel free to play with translating it, but keep in mind that the demo site resets at the top of the hour. If you&#8217;re seriously interested in translating our demo site&#8217;s content to go along with the nicely translated interface, <a href="http://groups.google.com/group/apostrophenow">join the Apostrophe google group</a> and drop us a line to get involved.</p>
<p>Interested in putting this power to work on your projects? Visit <a href="http://www.apostrophenow.com/">apostrophenow.com</a> to find out how we can help you. If you&#8217;re a Symfony developer or just a ballsy webmaster who doesn&#8217;t mind learning some new tricks, head straight for the <a href="http://trac.apostrophenow.org/wiki/ManualOverview">Apostrophe manual</a> to check out our installation guide. We do documentation in a big way.</p>
<p>We&#8217;d like to thank Quentin Dugauthier (French), Frank Wenzl (German), and Pablo Godel (Spanish) for their hard volunteer work on the translations. Others are working hard on Portuguese and Greek and have been patient through our growing pains as we mastered the fine points of UTF-8 and character sets in our translation system. We&#8217;ll be sure to thank them by name when they are done, so you don&#8217;t nag them too much now. (:</p>
<hr />
<p>There are, of course, other important fixes and improvements in Apostrophe 1.0.9, including one security fix. Here&#8217;s the list:</p>
<ul>
<li>A computer abandoned by an admin who has logged out can no longer be used to edit slots the admin previously edited using cleverly constructed URLs (only an issue on the same computer and if the PHP session has not ended). Note that you must upgrade your myUser class in apps/frontend/lib to extend aSecurityUser rather than sfGuardSecurityUser to get this fix (aSecurityUser is a subclass of the latter)</li>
<li>Global or virtual-page media slots can be edited successfully on Symfony pages that are not CMS pages</li>
<li>Unpublished pages no longer interfere with aNavigationAccordion layout</li>
<li>Fixtures no longer use HTML tags our filters remove on edit</li>
<li>Plaintext slots now autolink URLs and email address (obfuscated) as described in the manual</li>
<li>Search engine updates refactored, search engine now updates when you save page settings</li>
<li>&#8216;tool&#8217; option to rich text slots now correctly activates the FCK toolbar set name you specify</li>
<li>Slot save/cancel buttons now survive form validation passes properly (thanks to Spike)</li>
<li>Date widget is XHTML correct (thanks Spike)</li>
<li>Engines now work when the CMS is not mounted at the root of the site (important for those using the CMS as a subfolder of a site dominated by other Symfony modules)</li>
<li>Attempting to attach a list of zero items to a slideshow no longer results in adding all items in the media repository</li>
<li>Cross-browser and XHTML strictness fixes</li>
<li>Moved lib/base to lib/action (you must symfony cc)</li>
<li>Lost connections between existing media slots and media items when editing other media slots: fixed. Also, slideshows etc. are no longer removed on &#8220;cancel,&#8221; and selecting zero media items no longer selects all media items</li>
<li>i18n of over 99% of the admin interface (many thanks to Quentin, Galileo, Frank, Pablo and Fotis), new languages are regularly being added to the demo project&#8217;s apps/frontend/i18n folder</li>
<li>More convenient i18n of your site content (temporary titles supplied, all navigation controls work for pages whose titles are not yet translated)</li>
<li>Aesthetic upgrades</li>
<li>Superadmins can grant superadmin status</li>
<li>Some demo-specific styles moved from a.css to demo.css</li>
<li>Optional language selector in a/login partial</li>
<li>Global admin buttons now have separate names and labels (labels can be internationalized) and a documented way to add and reorder them in app.yml</li>
<li>Alpha channel is now preserved when rendering PNGs from a PNG original with gd (not available with netpbm)</li>
<li>Compact PDF slot style, without inline preview (you can override this in aMediaPDF/normalView if you want it back and you have ghostscript)</li>
<li>Better IE6 upgrade message</li>
<li>Various private methods now protected for easier app level overrides</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/24/apostrophe-speaks-your-language/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Apostrophe has a Point of View</title>
		<link>http://window.punkave.com/2010/03/22/apostrophe-has-a-point-of-view/</link>
		<comments>http://window.punkave.com/2010/03/22/apostrophe-has-a-point-of-view/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 22:05:08 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Apostrophe]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1051</guid>
		<description><![CDATA[
The Apostrophe Google Group has become pretty active lately. It has been so great to connect up with people around the world that are using Apostrophe to make sites for themselves or their clients. It feels great to be able to share something that we have labored long and hard on. It is especially exciting [...]]]></description>
			<content:encoded><![CDATA[<p><object width="500" height="194"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=10358888&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=10358888&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="194"></embed></object></p>
<p>The <a href="http://groups.google.com/group/apostrophenow">Apostrophe Google Group</a> has become pretty active lately. It has been so great to connect up with people around the world that are using Apostrophe to make sites for themselves or their clients. It feels great to be able to share something that we have labored long and hard on. It is especially exciting to know that we scratched our own itch and made something that works well for us and for <a href="http://trinity.duke.edu/">our clients</a>. It&#8217;s also exciting to see it helping with <a href="http://www.robertspeer.com/blog/apostrophenow-a-cms-so-easy-even-your-mom-could-use-it/">other peoples&#8217; itches</a>.</p>
<p>We love the passion that people have about Apostrophe. We have seen that in many forms including the suggestion of new features. What I want to make clear, though, is that <a href="http://apostrophenow.com">Apostrophe</a> does have a point of view embedded in all of the decisions that we make as we design and build it. If someone asks for a new feature, I always ask, &#8220;What problem are you trying to solve?&#8221; or &#8220;Can you describe a situation where the need for this feature came up?&#8221;</p>
<p>I think that surprises some people. They assume that our goal is to have the longest list of features of any web content management tool. In fact, that is not our goal. Our goal is to create a tool that is joyful to use while still being powerful.</p>
<p>The reason people fall in love with Apostrophe is because we have worked very hard to keep it simple and elegant. We are always going to ask the tough question of what problem does this solve. (Can it be solved with what is already built?)</p>
<p>We will never build a feature just because we wonder if it can be done. We are not in a feature race with anyone. We have found that sometimes people pick something based on a list of features, but our clients and users pick Apostrophe based on how they feel when they use it (think Tiffany&#8217;s, not Walmart). They feel empowered and excited. They have often mentioned the joyfulness of using Apostrophe. We have even heard people gasp and giggle when editing content for the first time.</p>
<p>All that said, we don&#8217;t want to be the solution for everyone, but we hope you enjoy using Apostrophe if it works for you.</p>
<p>________</p>
<p>Note: I just finished reading <a href="http://37signals.com/rework/">Rework</a> by Jason Fried and David Heinemeier Hansson of 37 Signals, and it reminded me that I should be putting down more of our thoughts on Apostrophe. These decisions have been embedded in Apostrophe from the beginning, but we have not always been good about communicating them.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/22/apostrophe-has-a-point-of-view/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Apostrophe: the bipartisan CMS</title>
		<link>http://window.punkave.com/2010/03/22/apostrophe-bipartisan-cms/</link>
		<comments>http://window.punkave.com/2010/03/22/apostrophe-bipartisan-cms/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 16:04:54 +0000</pubDate>
		<dc:creator>Johnny</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[apostrophenow]]></category>
		<category><![CDATA[awesome]]></category>
		<category><![CDATA[funny]]></category>
		<category><![CDATA[healthcare]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1045</guid>
		<description><![CDATA[Ok, so it&#8217;s Friday and we&#8217;re all psyched for the weekend:

ok ok, it&#8217;s Monday but you can&#8217;t let that stop the dance party!
]]></description>
			<content:encoded><![CDATA[<p>Ok, so it&#8217;s Friday and we&#8217;re all psyched for the weekend:</p>
<p><a rel="attachment wp-att-1046" href="http://window.punkave.com/2010/03/22/apostrophe-bipartisan-cms/politicians-are-funny-20954-1269261664-2/"><img class="alignnone size-full wp-image-1046" title="p'oliticians-are-funny" src="http://window.punkave.com/wp-content/uploads/2010/03/politicians-are-funny-20954-1269261664-2.jpg" alt="" width="500" height="325" /></a></p>
<p>ok ok, it&#8217;s Monday but you can&#8217;t let that stop the dance party!</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/22/apostrophe-bipartisan-cms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Faster, PHP! Kill! Kill!</title>
		<link>http://window.punkave.com/2010/03/08/faster-php-kill-kill/</link>
		<comments>http://window.punkave.com/2010/03/08/faster-php-kill-kill/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:39:41 +0000</pubDate>
		<dc:creator>Tom</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[fastcgi]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=1029</guid>
		<description><![CDATA[
PHP is easy&#8230; as programming languages go, that is. You can build sites in a real hurry. 
With frameworks like Symfony, you can build them faster still, and follow modern programming practices at the same time. 
And Apostrophe strips away yet another layer of effort if your site calls for a content management system.
Yes, Java [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://window.punkave.com/wp-content/uploads/2010/03/Screen-shot-2010-03-08-at-11.04.17-PM.png" alt="" title="Screen shot 2010-03-08 at 11.04.17 PM" width="216" height="284" class="alignnone size-full wp-image-1036" /><br />
PHP is easy&#8230; as programming languages go, that is. You can build sites in a real hurry. </p>
<p>With frameworks like <a href="http://www.symfony-project.org/">Symfony</a>, you can build them faster still, and follow modern programming practices at the same time. </p>
<p>And <a href="http://www.apostrophenow.com/">Apostrophe</a> strips away yet another layer of effort if your site calls for a content management system.</p>
<p>Yes, Java has more raw speed, all else being equal (which it never is). But as the LISP programmers used to say, &#8220;a moment of regret, a lifetime of convenience.&#8221;</p>
<p>Still, sooner or later success catches up with you and you want your site to cope with Serious Traffic&#8230; or cope with moderate traffic on a cheap virtual machine&#8230; or at the very least, not be dog-slow with just a handful of users on the system.</p>
<p>There&#8217;s a lot of advice out there about optimizing PHP code, some of it well worth your while. And there&#8217;s excitement about HipHop, Facebook&#8217;s new native code compiler for PHP. But these are drastic steps that require you to rewrite your code or adopt less proven and more awkward ways of delivering your code. </p>
<p>Justified? Sure, sometimes, on the biggest projects in the world (like Facebook) (*). But as Donald Knuth says, &#8220;premature optimization is the root of all evil.&#8221; That&#8217;s because tweaking your code for speed&#8217;s sake usually makes it harder to maintain and less adaptable to new requirements.</p>
<p>What most developers don&#8217;t realize is that there are three major factors that typically slow down PHP projects based on frameworks (like Symfony or, <em>sigh</em>, Drupal) so much that code profiling and database query redesign don&#8217;t even have a chance to become relevant factors. Fix these things first before you worry about other issues:</p>
<p><strong>1. Compiling code over and over and over.</strong> Would you wait for your Mac to recompile MacOS X from source code every time you boot it up? Of course not. How about every time you fill out a dialog box? That&#8217;s pretty much what you&#8217;re doing every time you access a PHP-driven website that doesn&#8217;t use a bytecode cache.</p>
<p><strong>2. Waiting and waiting and waiting for web browsers to make another request,</strong> pinning down web server processes that your other users need. By default Apache usually lets browsers hold on to a connection for up to 15 seconds just in case they ask for more. This is a good thing in many ways, but 15 seconds is far too long. Which leads us to #3:</p>
<p><strong>3. Tying up a &#8220;fat&#8221; web server process with PHP on board for every request,</strong> even requests for the zillions of little static PNGs that probably make up your page design. (**)  A typical Apache web server configuration with <tt>mod_php</tt> suffers from this flaw, fatally limiting the number of simultaneous users you can handle. </p>
<p>So what can we do about these problems? Quite a bit as it turns out. I&#8217;ll start with the low-hanging fruit and move on to the tougher stuff. The fascinating common thread with all of these suggestions: no changes at all to your PHP code.</p>
<p><span id="more-1029"></span></p>
<h2>Stop Recompiling Your World: APC</h2>
<p>APC, aka the Alternative PHP Cache, is a bytecode cache. What does that mean and what good does it do?</p>
<p>Today, when users visit your website, your web server struggles to translate all of your PHP code into a more manageable &#8220;bytecode.&#8221; And only then does it actually run the bytecode and output the page.</p>
<p>Bytecode isn&#8217;t true native machine code and doesn&#8217;t run as fast as compiled Java, and certainly not as fast as compiled C. That&#8217;s why Facebook&#8217;s HipHop project seeks to convert PHP code to C++, and then compile that to native code. But that&#8217;s a drastic step with far-reaching consequences for your project. Before you think about HipHop, try a simpler fix: stop throwing away the bytecode and starting over from zero on every new request that comes to the site! </p>
<p>In our experience, enabling APC reduces both memory usage and the time required to respond to a request by vast amounts. Even a simple action in Symfony or Drupal can implicitly require that quite a bit of PHP code be compiled. With APC, all of that code <i>stays</i> compiled, and that simple action actually runs quickly and simply. </p>
<p>APC is simply indispensable for serious PHP programming. Turn it on. Make sure it&#8217;s really working. And enjoy dramatic improvements in your social life, hair and skin.</p>
<h3>Installing APC</h3>
<p>Depending on your system, APC may already be installed or even, if you are very lucky, activated correctly. Virtual machine hosting from <a href="http://www.servergrove.com/">ServerGrove</a> comes with APC &#8220;out of the box.&#8221; Most shared hosting probably won&#8217;t because it increases the amount of memory pinned down for each user on the shared server, but if you care about your website&#8217;s speed, you&#8217;re not using shared hosting. Get a small, cheap virtual machine from ServerGrove instead (or if you must, do it the hard way and set up a Slicehost or linode virtual machine; you&#8217;ll learn a lot about system administration).</p>
<p>On our slicehost VMs, we found it necessary to install APC with pecl, the PHP package manager for extensions (like PEAR, but different in that they are not written in plain PHP):</p>
<pre>
pecl install apc
</pre>
<p>We then enable it in php.ini (you won&#8217;t be able to do this in a .htaccess file):</p>
<pre>
; Must enable APC otherwise we compile all of Symfony on every hit
extension=apc.so
; Give APC enough shared memory to handle Symfony, etc.
apc.shm_size = 48
apc.include_once_override = 1
apc.mmap_file_mask = /tmp/apc.XXXXXX
</pre>
<p>Then restart Apache:</p>
<pre>
apachectl restart
</pre>
<p>And you&#8217;re off to the races. The first page access will be as slow as ever, but subsequent accesses will be much, much faster. You can also check whether you&#8217;re saving memory and time using Symfony&#8217;s debugging toolbar. </p>
<p>Your system also likely has an <a href="http://www.electrictoolbox.com/apc-php-cache-information/">APC status page</a> that you can copy to your website to check out the current status of APC. It&#8217;s fun to play with.</p>
<h2>Dialing Back Keepalive: Too Much of a Good Thing</h2>
<p>In the beginning there was NCSA Mosaic, and it was pretty cool, all things considered. But it wasn&#8217;t fast.</p>
<p>Mosaic made only one request of a web server at a time. Trying to do more probably seemed rude. Besides, lots of web servers couldn&#8217;t cope with more than one request a time <i>at all</i>. But that would only happen if two users came along at once, and that was never gonna happen, right? </p>
<p>Ah, those were the (sad, lame, pathetic) days. Scroll to the present. Typical web browsers first request the page, say &#8220;hang on a minute,&#8221; open perhaps five <em>more</em> connections besides and then make note of all the images, JavaScript files, CSS files and other embedded bric-a-brac and start requesting all of those things. Consecutively and in parallel. Really a lot.</p>
<p>The Apache web server is actually very good at handling this. But by default, it is very generous: it lets the browser leave it hangin&#8217; for fifteen seconds. That means an Apache process and all of the memory it requires is tied up for all of that time, just doin&#8217; nothin&#8217;. And that&#8217;s bad news.</p>
<p>Fortunately it&#8217;s very easy to fix this in your <code>httpd.conf</code> file (actually, in our setups, this is usually in <code>apache2.conf</code>):</p>
<pre>
KeepAliveTimeout 2
</pre>
<p>Restart Apache:</p>
<pre>
apachectl restart
</pre>
<p>And you&#8217;ll find that your site can suddenly cope with higher loads. That&#8217;s because your&#8217;re not tying up valuable resources waiting around for more requests from browsers that are <i>already</i> using and reusing five other connections to your server. The browser is welcome to promptly request more files and finish its business with you, but not to stand around twiddling its thumbs while you wonder if you have a date or not.</p>
<p>You can turn keepalive off entirely, but doing so forces the browser to &#8220;call back&#8221; for each and every little image file on your page, which is a terrible idea. So use it&#8230; just don&#8217;t let it abuse you.</p>
<h2>MaxClients: Does This <code>mod_php</code> Make My Butt Look Big?</h2>
<p><code>mod_php</code> is fast. Unlike the old-fashioned &#8220;PHP as CGI&#8221; approach, <code>mod_php</code> keeps the PHP interpreter itself loaded in memory and ready to rock at all times, and that&#8217;s good.</p>
<p>But <code>mod_php</code> is also a pig. For a big-deal web application that wrangles lots of database objects, or makes thumbnails of uploaded images, or does pretty much anything cool, it&#8217;s not uncommon for a PHP process to use 50MB of memory or more. More miserly code can still hit 30MB without much difficulty.</p>
<p>We first ran into this problem when we wanted to move smaller client sites onto small VMs, so that they could have well-secured, highly-reliable web hosting at an affordable price. They tended to bog down and become unusable quickly.</p>
<p>We discovered that dialing back keepalive helped tremendously with the problem. And we also learned to do the math and figure out how many reasonably fat PHP Apache processes would really fit in the memory available to the slice, and configure Apache to run no more than that. In <code>httpd.conf</code>:</p>
<pre>
MaxClients          20
</pre>
<p>This may seem drastic (OMG! I can&#8217;t serve more than 20 simultaneous users!) but here&#8217;s the thing: you already can&#8217;t. If you try, if you leave this set to its much higher default, the result will be a VM crushed by the need to swap out all of these Apache processes to virtual memory while they are still trying to do work. As the operating systems geeks say, the &#8220;resident set size&#8221; of your Apache and PHP processes is bigger than your actual memory. And when that happens you&#8217;re SOL.</p>
<p>When you set MaxClients to a realistic number, what happens instead is this:</p>
<p><em>You can handle up to 20 connections at once gracefully.<br />
That 21st connection queues up and is dealt with soon after.<br />
If the average load doesn&#8217;t exceed 20 connections, you&#8217;re fine.</em></p>
<p>If too many connections queue up, some people will not get through. But <em>you</em> will still be able to get through to other services on the VM&#8230; like the ssh connection you use to administer it and change these settings. Without that, you&#8217;re stuck in a seesaw battle, shutting down your website, tweaking settings, firing it up again and watching it gradually become overwhelmed.</p>
<h3>What Is The Right MaxClients For Me?</h3>
<p>Take the amount of RAM in your server (for instance, a 256MB slicehost VM). Subtract a bit of overhead (at least 50MB, ideally more, bigger VMs are better that way). Now divide by the largest PHP process you typically see when running &#8220;top&#8221; or &#8220;ps -auxw | grep httpd&#8221; (you might have to grep for apache rather than httpd depending on your OS). For instance, if your processes top off around 30MB, you can set MaxClients to (256-30) divided by 30. Round down and you have a MaxClients setting of 7.</p>
<p>One snag: some operating systems show shared memory (like the memory used by APC) as memory in use by every one of the Apache processes, even though it is really only allocated once and shared by all of them. If your APC cache is set to 40MB and all of your PHP processes seem 40MB overweight, you can increase MaxClients somewhat to allow for this.</p>
<p>Yes, you can use swap space (virtual memory) to go higher, but this just forces the machine to swap, using disk space in place of memory to do hard things it needs to do quickly and freezing you out of your own machine. So don&#8217;t do that.</p>
<h2>PHP, I Love You, But Could You Sleep Downstairs?</h2>
<p>Dialing back the number of Apache processes is a helpful step that allows your server to say no with grace and style when there is too much traffic. But the underlying problem remains: we can&#8217;t deal with a lot of requests at once. And the reason we can&#8217;t do that is PHP. So we&#8217;re stuck. Or are we?</p>
<p>Our Apache processes are &#8220;fat&#8221; in terms of memory use because of the memory taken up by PHP. But most of the requests we&#8217;re handling are for little PNG files and not-so-little JPEG files and CSS files and JavaScript files&#8230; all of which Apache can serve up handily with about three bytes of memory and a piece of string. </p>
<p>The obvious solution is to serve PHP requests and static files separately. And many sites do this explicitly, using absolute URLs pointing at a different subdomain for static files. For example:</p>
<p>&lt;img src=&#8221;http://static.example.com/foo.png&#8221; /&gt;</p>
<p>Now, this is a fine thing and I have nothing against it. When you design things this way you can use entirely separate machines to serve these requests if you wish, and that&#8217;s pretty exciting from a performance perspective. Many bigger sites find this well worth their while.</p>
<p>But you are also complicating things. And you are forced to change working code, which introduces the potential for new and exciting bugs.</p>
<p>There&#8217;s another approach (well, one of many): FastCGI. FastCGI is an enhanced version of the CGI protocol that appeared quite early in the evolution of the web but caught on only with those most concerned about performance. I must admit I am a very recent convert, ironic since FastCGI is a bit out of vogue today. But there are solid reasons to consider using it.</p>
<p>FastCGI has three big advantages:</p>
<p>1. FastCGI runs PHP processes separately from Apache. That means Apache can stay lean and mean, not only running much smaller processes (and therefore perhaps many more of them) but even running in a separate &#8220;worker thread&#8221; that outperforms the separate-processes mode by a long mile. This is a big, big win.</p>
<p>2. It can reuse a single process for new PHP requests (***), avoiding the need to restart the PHP interpreter. That&#8217;s nice, but mod_php can do the same trick, and mod_php is capable of sharing APC cache memory between all of its processes. And FastCGI can&#8217;t do that&#8230; or it wouldn&#8217;t be able to without a little help from PHP:</p>
<p>3. PHP comes with a special FastCGI mode in which it manages several child processes of its own, and <strong>allows all of those processes to share a single APC cache.</strong> </p>
<p>Put these advantages together and you have the holy grail of PHP hosting: PHP running separately from Apache, but still maintaining all of the performance advantages of the APC cache. And we can do it without changing a line of PHP.</p>
<h3>Installing FastCGI</h3>
<p>There&#8217;s one catch: Apache 2.0 ships with <code>mod_cgid</code>, a rewritten version of FastCGI that complies with the official Apache license, instead of the oh-so-fractionally-different FastCGI license (****). And it&#8217;s nice and all, except that it completely lacks the third advantage of FastCGI I mentioned above. If you want the benefits I&#8217;m describing here, you have to use the real <code>mod_fastcgi</code>. Accept no substitutes.</p>
<p>These directions work for slicehost Ubuntu slices and other Ubuntu-based Linux. They will not work exactly as-is for servergrove which is centos-based:</p>
<p>Edit /etc/apt/sources.list<br />
Add multiverse, which includes software with insufficiently &#8220;open&#8221; licenses, such as mod_fastcgi. Change intrepid to the ubuntu version on your box, it&#8217;ll be mentioned all over sources.list:</p>
<pre>
# tom@punkave.com: we want multiverse support so we can have real mod_fastcgi
deb http://us.archive.ubuntu.com/ubuntu/ intrepid multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ intrepid multiverse
deb http://us.archive.ubuntu.com/ubuntu/ intrepid-updates multiverse
deb-src http://us.archive.ubuntu.com/ubuntu/ intrepid-updates multiverse
</pre>
<p>Now do:</p>
<pre>
apt-get update
apt-get install libapache2-mod-fastcgi
</pre>
<p>Now edit /etc/apache2/mods-available/fastcgi.conf to read:</p>
<pre>
&lt;IfModule mod_fastcgi.c&gt;
  # One shared PHP-managed fastcgi for all sites
  Alias /fcgi /var/local/fcgi
  # IMPORTANT: without this we get more than one instance
  # of our wrapper, which itself spawns 20 PHP processes, so
  # that would be Bad (tm)
  FastCgiConfig -idle-timeout 20 -maxClassProcesses 1
  &lt;Directory /var/local/fcgi&gt;
    # Use the + so we don't clobber other options that
    # may be needed. You might want FollowSymLinks here
    Options +ExecCGI
  &lt;/Directory&gt;
  AddType application/x-httpd-php5 .php
  AddHandler fastcgi-script .fcgi
  Action application/x-httpd-php5 /fcgi/php-cgi-wrapper.fcgi
&lt;/IfModule&gt;
</pre>
<p>Now set up /var/local/fcgi/php-cgi-wrapper.fcgi:</p>
<pre>
mkdir -p /var/local/fcgi/
vi /var/local/fcgi/php-cgi-wrapper.fcgi
</pre>
<p>Paste in:</p>
<pre>
#!/bin/sh

# We like to use the same settings we formerly used for apache mod_php.
# You don't want this if your php.ini is in /etc
PHPRC="/etc/php5/apache2"
export PHPRC
# We can accommodate about 20 50mb processes on a 1GB slice. More than that
# will swap, making people wait and locking us out of our own box.
# Better idea: just make people wait to begin with
PHP_FCGI_CHILDREN=20
export PHP_FCGI_CHILDREN
exec /usr/bin/php-cgi
</pre>
<p>Note the figure 20, this can be adjusted for the box in question if it has more or less memory to offer. Also note that we use the same php.ini we used with mod_php (/etc/php5/apache2). You can change that if you think it appropriate but don&#8217;t forget to bring settings over.</p>
<p>Set permissions:</p>
<pre>
chmod -R 755 /var/local/fcgi
</pre>
<p>IMPORTANT: comment out any php_value lines in .htaccess files for the sites on this box, and move those directives to php.ini. Otherwise you will get errors form those sites and they won&#8217;t work. </p>
<p>If two sites on the same slice really must have separate php.ini settings, consider separate slices for the sites. It&#8217;s possible to set up more than one fastcgi pool, but that halves the resources available and so on.</p>
<pre>
# Commented out; moved to /etc/php/apache2/php.ini
# php_value arg_separator.output &#038;
</pre>
<p>Disable mod_php5, enable mod_fastcgi in its place, enable mod_actions which is required by the above, and restart Apache:</p>
<pre>
a2dismod php5; a2enmod fastcgi; a2enmod actions; apache2ctl restart
</pre>
<p>Now test the site. Also check /var/log/error.log and/or error.logs for individual sites to make sure you see mentions of fastcgi and not mod_php.</p>
<p>If you get an error and you see this in the log:</p>
<pre>
[Thu Mar 04 02:51:33 2010] [alert] [client 69.141.215.7] (2)No such file or directory: FastCGI: failed to connect to (dynamic) server "/var/local/fcgi/php-cgi-wrapper.fcgi": something is seriously wrong, any chance the socket/named_pipe directory was removed?, see the FastCgiIpcDir directive
</pre>
<p>There&#8217;s a chance it&#8217;s just a transitory problem; first-time fastcgi startups seem to be a bit temperamental, but we&#8217;ve had no problems in the long haul. Restart apache again:</p>
<pre>
apache2ctl restart
</pre>
<p>If it still doesn&#8217;t work reenable mod_php5:</p>
<pre>
a2dismod fastcgi; a2enmod php5; apache2ctl restart
</pre>
<p>And do some more reading.</p>
<h3>Late-breaking news: PHP 5.3.3 and the new SAPI FPM</h3>
<p>In addition to the built-in support for managing FastCGI child processes in php-cgi, PHP 5.3.3 introduces a new PHP binary, php-fpm, that offers a superior implementation of FastCGI support. You don&#8217;t have to switch if you are happy with the FastCGI support in php-cgi, which is fortunate because your operating system might not offer PHP 5.3.3 or its new php-fpm binary (aka the SAPI FPM) yet.</p>
<p>Setting up the new SAPI is not that different from setting up FastCGI with php-cgi, provided you can get past the probable need to compile it yourself (of course, by the time you read this, there may be a php-fpm package in your favorite Debian repository).</p>
<p>Interested parties should <a href="http://www.php.net/manual/en/install.fpm.php">check out the new FastCGI Process Manager article on www.php.net</a>.</p>
<h3>Installing the Worker Thread MPM</h3>
<p>Once you reach this point successfully, you are ready to switch Apache from &#8220;prefork&#8221; mode (which mod_php requires) to &#8220;worker thread&#8221; mode. Worker thread mode is blindingly, ri<em>dun</em>culously fast at serving static stuff, and uses mod_fastcgi to take care of PHP. You can&#8217;t do this with mod_php enabled, so you must succeed in setting up fastcgi first (see above):</p>
<pre>
apt-get install apache2-mpm-worker
</pre>
<p>That will restart Apache by itself. But if not you can do so manually.</p>
<p>Now test the site again. If it doesn&#8217;t work, you can easily undo this:</p>
<pre>
apt-get install apache2-mpm-prefork
</pre>
<p>To verify success:</p>
<pre>
ps auxw | grep apache
</pre>
<p>Should show fewer processes (unless your operating system shows threads as processes). The processes you do have are running many threads (lightweight subprocesses that are exposed to each other&#8217;s memory etc. and generally less expensive).</p>
<p>ps auxw | grep php</p>
<p>Should show roughly 20 processes, plus a process to manage the others. Significantly more than 20 (say, 40+) indicates you goofed and didn&#8217;t set maxClassProcesses properly and you&#8217;re going to have a lot of PHP processes on your hands in a hurry, so fix that. (I&#8217;m assuming you chose 20 processes as your limit for PHP above.)</p>
<p>Now beat up on the site a bit. Remember to check any other sites on the same box, you just changed how all of your PHP sites on this box are run. </p>
<p>Now copy apc.php to the web folder of one of your sites and visit that URL to see a page giving stats about how well the cache is working. You should see a healthy percentage of cache hits if you have revisited some of the same pages or at least reused Symfony and Doctrine. If not check whether you ever enabled APC for this site. You can find apc.php in /usr/share/php/apc.php on some systems. Its absence doesn&#8217;t mean APC is not available.</p>
<p>You need to set up both mpm-worker and fastcgi to get the most benefit here. The worker MPM can serve zillions of static files in a hurry with minimal memory usage each. However, after setting up fastcgi, you can certainly crank up MaxClients and stick with the prefork MPM if you prefer.</p>
<h2>Alternatives</h2>
<p><strong>APC alternatives:</strong> there are alternatives to the APC cache. These include eAccelerator and Zend Optimizer. I&#8217;m not an expert on the others, but APC will be standard in PHP 6.0, so I recommend standardizing on it now. For extreme cases (i.e. &#8220;we&#8217;re getting as big as Facebook and we have too much code to start thinking about improving the code itself in any serious way&#8221;), by all means consider <a href="http://wiki.github.com/facebook/hiphop-php/">HipHop</a>. You can think of it as a distant relative of APC that provides a roughly 2x performance boost at a large cost in complexity and maintenance.</p>
<p><strong>FastCGI alternatives:</strong> some will disagree with my recommendation of FastCGI. mod_cgid supposedly has better child process management&#8230; with the glaring exception that APC is not shared, ballooning your memory requirements in a seriously ugly way. Better alternatives include running the <a href="http://nginx.org/en/">nginx</a> (pronounced &#8220;engine X&#8221;) web server as a lightweight &#8220;front end&#8221; that serves static files directly and proxies other requests through to an Apache server running mod_php. One can also run Apache (without the fat mod_php module) as a front end for another instance of Apache. In these setups, the back-end Apache doesn&#8217;t accept connections except from the front-end one, and Apache&#8217;s reverse proxy features come into play. Personally I like the simplicity of Apache communicating directly with a master PHP process via the FastCGI protocol.</p>
<h2>Conclusion</h2>
<p>ERRRRRRRRRRRROOOOOMMMMMMM</p>
<p>Beep beep</p>
<p>ERRRRRRRRRRRRRRRRRROOMMMMMMMM</p>
<p>[HONK]</p>
<p>Zoom!</p>
<p>(*) Actually, one of Facebook&#8217;s stated goals for HipHop is to avoid rewriting and presumably hand-optimizing their existing PHP code. They have billyuns and billyuns of lines of PHP code, not all of it written by hardcore software jocks. So if a handful of smart folks can make mediocre PHP run 50% faster, that&#8217;s a big deal for Facebook. For most of us it makes more sense to pick the low-hanging fruit first (see all of the above), and then stop making separate SQL queries for every single darn object on the page, and <em>then</em> maybe think about HipHop. I&#8217;m not knocking HipHop here at all, it&#8217;s an impressive technical accomplishment. But if you&#8217;re starting with HipHop as your<br />
first optimization, you&#8217;re not paying attention.</p>
<p>(**) Yes, you could use CSS sprites to speed these up, and given time you probably should, but in the short term let&#8217;s talk about ways to deliver them quickly without getting bogged down in hard-to-maintain optimizations. With HTTP keepalive working for us instead of against us, the performance difference between delivering 20 PNGs and one PNG is mostly on the browser side&mdash; still good to avoid, but not a brutal impact on your web server. One step at a time, okay?</p>
<p>(***) Yes, FastCGI is capable of running lots of things other than PHP, but this is a PHP article. So: neener.</p>
<p>(****) There&#8217;s nothing wrong with the FastCGI license. It&#8217;s <a href="http://www.fastcgi.com/devkit/LICENSE.TERMS">a very boring MIT-style license</a> that shouldn&#8217;t interfere with your commercial use.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/03/08/faster-php-kill-kill/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Apostrophe 1.0!</title>
		<link>http://window.punkave.com/2010/02/11/apostrophe-1-0/</link>
		<comments>http://window.punkave.com/2010/02/11/apostrophe-1-0/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 03:26:57 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=931</guid>
		<description><![CDATA[We have labored long and hard to prepare for the 1.0 release of Apostrophe. As we said before, it has been stable and in use for a long time now, but we wanted to  mark a moment in time with an official release.
Probably the easiest way to get a feel for Apostrophe is to [...]]]></description>
			<content:encoded><![CDATA[<p>We have labored long and hard to prepare for the 1.0 release of Apostrophe. As we said before, <a href="http://window.punkave.com/2010/02/08/apostrophe-1-0-release-wednesday/">it has been stable and in use for a long time now</a>, but we wanted to  mark a moment in time with an official release.</p>
<p><span style="font-weight: normal;">Probably the easiest way to get a feel for Apostrophe is to </span><strong>go to our </strong><a href="http://demo.apostrophenow.com/"><strong>demo site</strong></a><strong> and login. The user name is &#8220;admin&#8221; and the password is &#8220;demo&#8221;.</strong><span style="font-weight: normal;"> Keep in mind that the content resets itself every hour on the hour.</span></p>
<p>If you want to get your bearings before you you do that, head over to the newly revamped <a href="http://apostrophenow.com">Apostrophe</a> site. For the very interested, you should consider checking out our extensive <a href="http://www.apostrophenow.com/home/readme">README</a> which includes an Installation section, an Editor&#8217;s guide, a Designer&#8217;s guide and a Developer&#8217;s guide.</p>
<p>Now for some of the highlights.</p>
<h2>Slots!</h2>
<p><a title="Apostrophe Slot Buttons by P'unk Ave, on Flickr" href="http://www.flickr.com/photos/punkavenue/4355023008/"><img src="http://farm3.static.flickr.com/2679/4355023008_2dc0742811_o.jpg" alt="Apostrophe Slot Buttons" width="480" height="78" /></a></p>
<p>There are rich text, image, slideshow, video, button, PDF, Raw HTML, and other slots built in. If you have used Apostrophe before, you know that you can add a slot on a page, choose what you want to place and then reorder it. New custom slots can also be made for any project.</p>
<h2>Slot Options</h2>
<p><a href="http://www.flickr.com/photos/punkavenue/4354278519/" title="Apostrophe Slideshow: Compact Option by P'unk Ave, on Flickr"><img src="http://farm3.static.flickr.com/2463/4354278519_b56665a5f5_o.jpg" width="223" height="151" alt="Apostrophe Slideshow: Compact Option" /></a></p>
<p>For some time we have wanted to be able to give you more fine control of a specific slot. For instance, what if you wanted to make the background color of a some text slots yellow, and some white? In the past that would have required two slots. Now, it can just be an option of the same text slot. In this screenshot, you can see that we allow you to switch between different types of slideshows. Make sure you try that out in the demo. It is probably our favorite new feature. We really sweated the details on making sure the option control was contextual. We hope you appreciate the effort.</p>
<p>There are many other new features and highlights, but for the moment I will leave you to find them in the <a href="http://demo.apostrophenow.com">demo</a> (remember: user is &#8220;admin&#8221; and password is &#8220;demo&#8221;) or in the <a href="http://www.apostrophenow.com/home/readme">documentation</a>. (We promise to highlight these in future posts.)</p>
<h2>So, what does this mean to you?</h2>
<p>Well, it depends. If you are a PHP developer with <a href="http://www.symfony-project.org/">Symfony</a> skills you can get started today. From our README:</p>
<blockquote><p>Right now Apostrophe is best suited to PHP developers who want to make an intuitive content management system available to their clients. Apostrophe is very easy for your clients to edit, administer and maintain once it is set up. Right now, though, Apostrophe installations does call for some command line skills and a willingness to learn about <a href="http://www.symfony-project.org/">Symfony</a>. We are working to reduce the learning curve.</p></blockquote>
<p>If you are a front-end developer and want to get started using Apostrophe, <a href="mailto:geoff@punkave.com">talk to us</a>. We are in the process of working out a package where we set up a staging server with <a href="http://www.symfony-project.org/">Symfony</a> and <a href="http://www.apostrophenow.com/">Apostrophe</a> running on it. We would train you on templating in Apostrophe and you should be up in running in a day or two.</p>
<p>If you don&#8217;t want to go that route, here is what we suggest:</p>
<blockquote><p>Front-end developers who do not yet have PHP and Symfony skills but wish to set up an Apostrophe site by themselves should consider tackling the Symfony tutorial to get up to speed. It&#8217;s not necessary to complete the entire tutorial, but it helps to have at least a passing familiarity with Symfony.</p></blockquote>
<p>If you just think Apostrophe is rad and you want one&#8230; like now, <a href="mailto:geoff@punkave.com">just drop us a line</a>. We would be happy to design and implement an Apostrophe site for you. You would be joining some good company if you do.</p>
<h2>Surprise!</h2>
<p>We (more accurately <a href="http://window.punkave.com/author/tom/">Tom</a>) decided to build an extra slot last night as a gift for making you wait an extra day. Isn&#8217;t that nice of us (him)?</p>
<p>If you are observant you may have noticed an extra slot in the screenshot above. So without further ado, we present the Feed Slot (commonly referred to as the RSS Feed slot, but it will take Atom feeds as well). Use this to bring in your Twitter updates or maybe our <a href="http://www.apostrophenow.com/svn.rss">Apostrophe SVN code commit feed</a>.</p>
<p>Feel free to thank us anytime. (We like expensive beer.)</p>
<p>This is really just the beginning. We hope you have an opportunity to <a href="http://demo.apostrophenow.com/">check out Apostrophe</a>. We would love to <a href="mailto:geoff@punkave.com">hear from you</a> if you do. Comments below would be much appreciated (and read), as well.<br />
__________________</p>
<p>Don&#8217;t forget to follow us on Twitter for on-going updates: <a href="http://twitter.com/apostrophenow">@apostrophenow</a></p>
<p>If you are a developer, the <a href="http://trac.apostrophenow.org/">Apostrophe Trac</a> is the home of the open source community. On that site you can open support tickets, browse and contribute to the Wiki, and access and potentially contribute to the source code via svn (you&#8217;ll need to contact us if you want write access).</p>
<p>Also, please join the <a href="http://groups.google.com/group/apostrophenow">Apostrophe Google Group</a> if you want to tap into the community of people using Apostrophe to get support and help.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/02/11/apostrophe-1-0/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Oh So Close!</title>
		<link>http://window.punkave.com/2010/02/10/oh-so-close/</link>
		<comments>http://window.punkave.com/2010/02/10/oh-so-close/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 02:18:06 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Apostrophe]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=910</guid>
		<description><![CDATA[
We have decided to push back the release of Apostrophe 1.0 until tomorrow. 
We are truly in the home stretch. Just hitting a few bugs, finishing up documentation and adding some instructional content to the demo site. To tide you over, we are publishing this screencast of how you add video to a project by [...]]]></description>
			<content:encoded><![CDATA[<p><object width="500" height="425"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9366056&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=9366056&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="425"></embed></object></p>
<p>We have decided to push back the release of <a href="http://apostrophenow.com">Apostrophe</a> 1.0 until tomorrow. </p>
<p>We are truly in the home stretch. Just hitting a few bugs, finishing up documentation and adding some instructional content to the demo site. To tide you over, we are publishing this screencast of how you add video to a project by searching YouTube from within Apostrophe. Note how we bring in associated metadata (url, title, etc). For the record, you can add video by pasting in embed codes from countless other services like Viddler and Vimeo. </p>
<p>Please tune back in tomorrow.</p>
<p>P.S. We are not blaming the snow for the delay, but did want to note that we are certainly under a deep white blanket here in Philadelphia.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/02/10/oh-so-close/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Apostrophe 1.0 Release&#8230; Wednesday!</title>
		<link>http://window.punkave.com/2010/02/08/apostrophe-1-0-release-wednesday/</link>
		<comments>http://window.punkave.com/2010/02/08/apostrophe-1-0-release-wednesday/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 22:44:07 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[Apostrophe]]></category>

		<guid isPermaLink="false">http://window.punkave.com/?p=900</guid>
		<description><![CDATA[
If you follow us carefully, you have probably already seen this screencast of Apostrophe, our open source content management system built in the Symfony PHP Web Framework. You also probably know that we have built many sites with it at Duke University (Trinity College, Theater Studies, Economics, Evolutionary Anthropology, etc) and others like the Kimberton [...]]]></description>
			<content:encoded><![CDATA[<p><object width="500" height="375"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=7172499&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=7172499&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=0&amp;color=ff9933&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="500" height="375"></embed></object></p>
<p>If you follow us carefully, you have probably already seen this screencast of <a href="http://www.apostrophenow.com/">Apostrophe</a>, our open source content management system built in the <a href="http://www.symfony-project.org/">Symfony PHP Web Framework</a>. You also probably know that we have built many sites with it at Duke University (<a href="http://trinity.duke.edu/">Trinity College</a>, <a href="http://theaterstudies.duke.edu/">Theater Studies</a>, <a href="http://econ.duke.edu/">Economics</a>, <a href="http://evolutionaryanthropology.duke.edu/">Evolutionary Anthropology</a>, etc) and others like the <a href="http://www.kimberton.org/">Kimberton Waldorf School</a>, the <a href="http://askemap.org/">Environmental Management Assistance Program</a>, and <a href="http://dcsphila.org/">Diversified Community Services</a>. Since it is an open source project, other teams have used Apostrophe to power their sites to provide easy content management, as well.</p>
<p>You may be wondering why we haven&#8217;t made an official 1.0 release to date? </p>
<p>The answer is simply that every time we were going to do that, we decided that it could use one more cool feature or could be re-factored in this way or that. No regrets, though. For this first official 1.0 release, we have done so many under-the-hood changes and updates that we are glad we waited.  </p>
<p>I wanted to post to let you know that we will be sharing screencasts and screenshots of features over the next few days leading up to the release (and beyond). Hold on to your hat and get ready for the ride.</p>
<p>Coincidently, we are timing this release so that it was ready for <a href="http://www.symfony-live.com/">Symfony Live</a>. Tom will be in attendance spreading the good word. If you are planning on being there, drop us a line so Tom can buy you a drink.</p>
]]></content:encoded>
			<wfw:commentRss>http://window.punkave.com/2010/02/08/apostrophe-1-0-release-wednesday/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
