The Stochastic Game
Ramblings of General Geekery

Previewing a baked site in IIS/Apache

This is the first post of a series of things I learned while using PieCrust.

If you’re using PieCrust as a static website generator, you know you can use the built-in development server to preview your site as you’re modifying it. This is all pretty nice but there are plenty of good reasons to not go that way, the top ones being:

  1. The development server doesn’t run any custom scripts you may have.
  2. IIS, Apache and all the other well-known web-servers are faster and more robust.
  3. You can’t use special features like .htaccess or web.config settings.

If you went with the recommended directory structure for your site, you will have all your content in a _kitchen directory ready to be baked into your final website. But this _kitchen directory really looks a lot like a regular PieCrust website when PieCrust is used as a lightweight CMS. The only difference is that there’s no main index.php file, and that you may be using some file processors.

If you create an index.php file to bootstrap the _kitchen website, it would get deployed to your export directory when you bake your site, so you need to do one of the following:

  • Write some PHP wrapper to the chef baking utility to exclude that file from baking (you can pass a “skip_pattern” parameter to the baker class). I’ll try to make it easier to add exclude rules to chef in the near future, but at the moment you would need to write some code. Not ideal.
  • Rename the bootstrap file _index.php, since all files or directories with a leading underscore in their names are excluded. Now, however, you will need to edit your .htaccess or web.config to add _index.php as a default document, but that’s really just one line of text or a couple clicks. That’s the solution I use.

If you use file processors, you may have to work around them, which may not be possible. I myself only use the LESS CSS processor, and it’s easy to avoid it because LESS comes with a client-side Javascript processor. The trick is now to switch between the client and server side processors, which can be done with a few Twig macros:

{% macro stylesheet(baker, path, media) %}
{% if baker.is_baking %}
<link rel="stylesheet" href="{{ path }}.css" type="text/css" media="{{ media|default('all') }}" />
{% else %}
<link rel="stylesheet/less" href="{{ path }}.less" type="text/css" media="{{ media|default('all') }}" />
{% endif %}
{% endmacro %}

This macro emits a reference to a stylesheet that points to the standard CSS file if the website is currently being baked (which means the server-side processor will run to generate that CSS file), or points to the LESS file itself otherwise (which means the processor will run on the client).

{% macro less_js(baker, site_root) %}
{% if not baker.is_baking %}
<script src="{{ site_root }}js/less-1.0.41.min.js" type="text/javascript"></script>
{% endif %}
{% endmacro %}

This second macro adds the client-side processor to your page if the baker is not running.

Now you just need to call those macros from your template file(s):

{{ less.stylesheet(baker, site.root ~ 'styles/my-awesome-stylesheet', 'screen, projection') }}
{{ less.less_js(baker, site.root) }}

Update (PieCrust >= 0.0.3)

Recent versions of PieCrust have, at last, the ability to define which files should be excluded from baking. This means you can rename the bootstrap file back to index.php if you wish, and exclude it from the bake along with any .htaccess or web.config:

baker:
    skip_patterns:
        - /^_/
        - index.php
        - .htaccess
        - web.config

This is much better!