Changeblog - Blueprint/changeblog
2009-03-26T00:00:00Z
blueprint.inventivelabs.com.auSpiders and robots/changeblog/post/spiders-and-robots/
2009-03-26T14:34:36Z
Joseph Pearson<p>A couple of new, related features for Blueprint sites.</p>
<p>Firstly, you can define rules that prevent search engine spiders and other robots from accessing various parts of your site. Why would you do this? Really just to improve the efficiency of your site, and the relevance of the site content that search engines are storing. For instance, you don't want search engine spiders adding stuff to their personal shopping basket.</p>
<p>Most big sites provide some degree of direction to search engines as to what should be indexed, using the <a href="http://www.robotstxt.org">robots.txt</a> standard — here, for instance, is <a href="http://www.google.com/robots.txt">Google's robots.txt file</a>.</p>
<p>Blueprint gives you an easy way to define the robots.txt rules for a site. In <code>lib/rules.rb</code>, use the <code>robots_disallow</code> method to deny specific robots access to specific resources. Here's some examples:</p>
<pre><code># No robot should access the individual images for the gallery.
robot_disallow '*' => '/gallery/image'
# ...except Google.
robot_disallow 'Google' => ''
# The Yahoo robot shouldn't be allowed to see the Foo or Bar top-level pages.
robot_disallow 'Yahoo' => ['/foo', '/bar', 'add_to_basket']
</code></pre>
<p>Custom blueprints can define their own robots rules, which apply to any site that employs them. The SHP blueprint already uses this to explicitly deny access to its various basket-related actions.</p>
<p>Concomitant with this change is Blueprint's very own spider. You can use this to test that all internal links on your site are working. It flags any HTTP status code above 399 (eg, 404, 411, 500, etc), and any ingredient errors. Here's an example:</p>
<pre><code>$ rake site:spider domain=inventivelabs.com.au
SPIDERING [inventivelabs.com.au]
[200] http://inventivelabs.com.au/ -- 1.782209s
[200] http://inventivelabs.com.au/weblog/post/peeking-at-previews-in-blueprint -- 1.422189s
[200] http://inventivelabs.com.au/weblog/post/not-bad-for-a-one-year-old -- 0.967232s
[200] http://inventivelabs.com.au/weblog/post/5-minute-redesign-ebay -- 0.825736s
[200] http://inventivelabs.com.au/weblog/post/using-blueprint-as-a-drafting-tool -- 0.973908s
[200] http://inventivelabs.com.au/weblog/post/a-bloggie-for-ms-fits -- 0.825474s
[200] http://inventivelabs.com.au/weblog/post/harry-we-are-here-to-help -- 0.801349s
[200] http://inventivelabs.com.au/weblog/post/eight-days-at-the-labs -- 0.988544s
[200] http://inventivelabs.com.au/weblog/post/the-other-things -- 1.06554s
[200] http://inventivelabs.com.au/weblog/post/migrating-from-lighthouse-to-redmine -- 1.221826s
[200] http://inventivelabs.com.au/weblog -- 0.927285s
[200] http://inventivelabs.com.au/weblog/post/harry-we-are-here-to-help#comments -- 1.06135s
[200] http://inventivelabs.com.au/the-way-we-work -- 3.964896s
[200] http://inventivelabs.com.au/about-the-labs -- 2.099506s
[200] http://inventivelabs.com.au/blueprint -- 0.838506s
[200] http://inventivelabs.com.au/blueprint/screencast -- 0.655021s
[200] http://inventivelabs.com.au/portfolio -- 2.039005s
[200] http://inventivelabs.com.au/portfolio/project/resicon -- 0.860806s
[200] http://inventivelabs.com.au/portfolio/project/rmit-sro-database -- 0.747917s
[200] http://inventivelabs.com.au/portfolio/project/big-and-little-films -- 0.856033s
[200] http://inventivelabs.com.au/portfolio/project/australians-all -- 0.920293s
[200] http://inventivelabs.com.au/portfolio/project/cyclopharm -- 0.860129s
[200] http://inventivelabs.com.au/portfolio/project/shane-maloney -- 0.921109s
[200] http://inventivelabs.com.au/portfolio/project/register-of-urban-design-practices -- 0.923032s
[200] http://inventivelabs.com.au/portfolio/project/scribe-website-and-business-system -- 0.98052s
[200] http://inventivelabs.com.au/portfolio/project/iaia-reference-finder -- 0.921664s
[200] http://inventivelabs.com.au/portfolio/project/unico -- 0.922174s
[200] http://inventivelabs.com.au/portfolio/project/mcculloch-mcculloch-website -- 0.737803s
[200] http://inventivelabs.com.au/portfolio/project/readings -- 1.003813s
[200] http://inventivelabs.com.au/portfolio/project/plans-at-work-software-and-website -- 0.760026s
[200] http://inventivelabs.com.au/portfolio/project/back-to-back-theatre-website -- 1.073601s
[200] http://inventivelabs.com.au/portfolio/project/text-publishing-website -- 0.73745s
[200] http://inventivelabs.com.au/static/dark.css -- 1.054769s
[200] http://inventivelabs.com.au/static/style.css -- 0.993249s
[200] http://inventivelabs.com.au/static/images/apple-touch-icon.png -- 2.546059s
[200] http://inventivelabs.com.au/static/images/favicon.ico -- 0.519485s
[200] http://inventivelabs.com.au/static/files/assets/32bfd614/lighthouse_import.rake -- 1.212854s
[200] http://inventivelabs.com.au/weblog/post/the-writing-s-on-the-magnetic-wall -- 5.4549s
[200] http://inventivelabs.com.au/blueprint/ -- 1.267579s
</code></pre>
<p>You've got a few different ways to invoke the spider; to see them all, run:</p>
<pre><code>$ rake -Tspider
</code></pre>
<p>It's pretty basic right now, but we'll be adding features to it over time.</p>
Site helper methods/changeblog/post/site-helper-methods/
2009-03-13T17:35:21Z
Joseph Pearson<p>A helper method is a method that is available to any of your templates, and outputs a string (normally of HTML).</p>
<p>You can now define helper methods for particular sites. Just edit <code>lib/site_helper.rb</code> and write your own methods. This change should reduce some of the current reliance on ingredients. Remember that ingredients are still good for HTML-heavy snippets, but helper methods are probably better for logic-intensive stuff.</p>
<p>See the comments of the default <code>site_helper.rb</code> for more info.</p>
Rewriting URLs/changeblog/post/rewriting-urls/
2009-03-13T17:31:57Z
Joseph Pearson<p>You can now define regular expressions for redirecting certain URLs to other URLs. This has been possible with the 'URL Rewrites' sidebar box in the Settings tab, but it was always a bit hit and miss, and only invoked when Blueprint would ordinarily return a 404 response.</p>
<p>Now URL rewriting (or 301 redirecting, more precisely) occurs when much earlier in route recognition, before page slugs are checked. So you can override page slugs to point particular URLs elsewhere. 'Elsewhere' can be some other URL on the same site, a subdomain, or anywhere on the web.</p>
<p>To set up a URL rewrite, add it to <code>lib/rules.rb</code> in your site directory:</p>
<pre><code>rewrite /^\/artists\/\d+-(.*)$/ => '/artists/\1'
</code></pre>
<p>See the default <code>rules.rb</code> file for additional details.</p>
How hidden pages work/changeblog/post/how-hidden-pages-work/
2009-03-13T17:05:43Z
Joseph Pearson<p>In the latest Blueprint trunk, the behaviour of hidden pages has been subtly but significantly changed.</p>
<h3>How they used to work</h3>
<p>It used to be that if a page was hidden, then all of its descendents were hidden too. There was no way to view the <em>default action</em> (typically <code>index</code>) on these pages. They did not show up in site navigation.</p>
<p>You could still view any other action on a hidden page by explicitly specifying an action in the URL. This was useful for search pages primarily, where the search page was hidden, but you could still view results, tag results and tag clouds.</p>
<p>In general however, hidden pages were designed for ingredients -- you could specify the page slug of a hidden page in the ingredient call and get to one of its actions by that means.</p>
<h3>How they work now</h3>
<p>Pages now have a 'visibility' setting, which is one of:</p>
<ul>
<li>inherited</li>
<li>visible</li>
<li>hidden</li>
</ul>
<p>The default is 'inherited'. When a page has a visibility of 'inherited', it takes the visibility of its parent page. Top-level pages with 'inherited' visibility are regarded as 'visible'. So the default behaviour is unchanged -- if you set a page to be hidden, by default all of its children will be hidden too.</p>
<p>But now you can explicitly set a child (or grandchild, etc) of a hidden page to be 'visible'. All of its actions (including its default action) are accessible via its URL.</p>
<p>Because of the way the <code>render_in_hierarchy</code> template helper works, these children of hidden pages will not show up in the navigation elements that use this helper. But you can iterate over and link to visible children of hidden pages. And if you start the <code>render_in_hierarchy</code> helper with those children, it'll work just fine too.</p>
<p>This should be a much more intuitive method of working with hidden pages, and makes things like footers and selective navigation much easier.</p>
<p>But note that you will no longer be able to access any actions of a hidden page, even by putting them in the URL, unless the page is defined to permit that action. At present, only the Search blueprint allows this, and only on the <code>results</code>, <code>tag</code> and <code>tag_cloud</code> actions. I'm pretty sure no-one's using this removed feature for any other purpose, but sing out if you are.</p>
Ingredient API changes/changeblog/post/ingredient-api-changes/
2009-03-13T16:44:50Z
Joseph Pearson<p>There have been a few changes under the hood for ingredients recently. All the changes are designed to be backwards-compatible, but there are some neat new aspects to them, and the old way of including them is now deprecated.</p>
<p>Because page ingredients (where you're referring to an action on a particular page) are more involved than site ingredients (where you just drop a template from the ingredients directory into your code), we've split them up into separate calls: <code>page_ingredient</code> and <code>site_ingredient</code>.</p>
<p>Using the old <code>ingredient</code> method continues to work (and will probably never stop working), but we recommend that you move to this new API -- if for now other reason than to make it clear in your head what you are doing with an ingredient.</p>
<p>A bonus: you can now pass local variables into page ingredients, which was not possible before.</p>
<p>There's much more detail on how ingredients now work <a href="http://blueprint.inventivelabs.com.au/documentation/blueprint-for-designers/ingredients">in the documentation</a>.</p>
The Design tab/changeblog/post/the-design-tab/
2009-01-16T15:40:16Z
Joseph Pearson<p>Blueprint's Design tab in the Admin area has finally been overhauled. Now you can edit any file in the site directory, create new templates/layouts/stylesheets/javascripts and upload images. You can even delete unneeded files. It's really very simple, but powerful enough to build a site without leaving the browser.</p>
<p>Here's a screenshot:</p>
<p><a href="http://blueprint.inventivelabs.com.au:80/static/files/assets/58c36e7a/blueprint-ide.png" title="Blueprint-ide" rel="lightbox"><img alt="Blueprint-ide" class="large" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/58c36e7a/blueprint-ide.png" title="Blueprint-ide" /></a></p>
<p>Also new: you can now have multiple layouts for a single site. Just create your additional layouts in the site directory, named something like: <code>raw.layout.html.erb</code>. This will make the <code>raw</code> layout available for your pages in the Structure tab — to wit:</p>
<p><a href="http://blueprint.inventivelabs.com.au:80/static/files/assets/96310439/blueprint-multi-layouts.png" title="Blueprint-multi-layouts" rel="lightbox"><img alt="Blueprint-multi-layouts" class="large" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/96310439/blueprint-multi-layouts.png" title="Blueprint-multi-layouts" /></a> </p>
<p>Naturally, if you only have the default layout, this dropdown is not visible on the Structure tab.</p>
Blueprint has an installer/changeblog/post/blueprint-has-an-installer/
2009-01-07T13:24:15Z
Joseph Pearson<p>As of last night, Blueprint has an installer. This means that once you've checked out the Blueprint code from our repository, you can run:</p>
<pre><code>ruby script/install
</code></pre>
<p>This will fetch all required gems, then pop open the install wizard in your web browser. The screencast below demonstrates how to go from a fresh Blueprint checkout to a website in under two minutes:</p>
<p><a href="http://blueprint.inventivelabs.com.au:80/static/files/assets/752f251a/installer.mov"><img alt="Installer poster" class="large" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/23e136b7/installer_poster.png" title="Installer poster" /></a></p>
<p>Of course, you only have to do this once on your development machine, and then you can create as many sites as you like. It's really easy to reconfigure Blueprint at a later stage, too.</p>
Login is required for staged sites/changeblog/post/login-is-required-for-staged-sites/
2008-12-18T16:25:03Z
Joseph Pearson<p>In a recent commit, we made it mandatory for anyone accessing the public part of a site on the staging server to log in. Previously you only had to log in to access the admin area of a staged site.</p>
<p>This change is for you and your clients' benefit: it protects the public site from prying eyes — search engines, spammers, lucky guessers — while you prepare the design and content for launch.</p>
<p>However, this does mean that you'll need to create a user account for anyone who you want to view the site. If they shouldn't have access to the admin area, we advise that you create a special role — say 'Observer'? — that has no ticked capabilities, and assign it to these users. Simple.</p>
<p>The other implication of this change is that staged sites are no longer aggressively cached as they are in production, so they'll be marginally slower as a result. Don't worry, it'll all be zippy when you go live.</p>
Windows support/changeblog/post/windows-support/
2008-12-18T16:16:33Z
Joseph Pearson<p>Microsoft Windows is now a supported Blueprint development platform. Instructions for installing and configuring Blueprint are in the Documentation section of this site: <a href="http://blueprint.inventivelabs.com.au:80/documentation/getting-set-up/your-computer-windows">Your Computer (Windows)</a>.</p>
<p>On a tangential note, as of today you can add notes to most pages in the Documentation section — advice and tips for yourself and other users of this site. Please feel free to add to everyone's Blueprint documentation!</p>
Expiring caches with the passage of time/changeblog/post/expiring-caches-with-the-passage-of-time/
2008-11-25T16:31:35Z
Joseph Pearson<p>Until now, if you created a blog post in a Blueprint site and set it to publish in three days, it would not appear on the site automatically in three days. Instead, it would appear whenever any site data changed <em>after</em> that three days had elapsed (ie, when the site cache was purged). </p>
<p>With active sites, this has never really mattered — purges occur frequently enough that the cached pages stay fresh. With less frequently updated sites however, pages can get really stale.</p>
<p>I've just introduced an additional task to the Blueprint itinerary which purges the cache of any site that has one or more items being published that day. This resolves that problem.</p>
<p>There are a few other dates and times stored in the various blueprints that might affect the content of the site as they pass. The <code>start_date</code> and <code>end_date</code> of an Event, for instance, or the <code>available_date</code> of a Product.</p>
<p>You can flag these cache-sensitive dates in the <code>blueprint_model</code> declaration for the model — here's what it might look like for <code>EvtEvent</code>:</p>
<pre><code>blueprint_model(
:cache_sensitive => [:start_date, :end_date],
)
</code></pre>
<p>For any specified date, just after midnight on that date the site cache will be purged.</p>
<p>For any specified datetime, the site cache will be purged just after the midnight following that moment in time.</p>
Per-page editing permissions/changeblog/post/per-page-editing-permissions/
2008-11-21T11:44:53Z
Joseph Pearson<p>Just introduced to Blueprint is the new per-page permissions feature. From the Structure tab, you can now assign an <strong>access role</strong> to each page.</p>
<p>Once assigned, only users belonging to that role — or to <em>any</em> role that allows editing pages from the Structure tab — may edit that page via the Content tab. This include creating posts, configuring the page, et cetera. </p>
<p>Users who don't have permission to edit a page will see it greyed out, with a lock icon replacing the normal page icon, in the Content tab.</p>
<p><img alt="Ppperms" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/f21406ba/ppperms.png" title="Ppperms" /> </p>
<p>You can <code>svn up</code> and <code>rake db:migrate</code> to start using this new feature.</p>
Tools for optimising your templates/changeblog/post/tools-for-optimising-your-templates/
2008-11-11T10:06:38Z
Joseph Pearson<p>I've just checked in a couple of new methods that might help you figure out the bottlenecks that are slowing down the rendering of your templates.</p>
<p>They are:</p>
<ul>
<li><code>bench_marker</code> — takes a "label" argument describing this point in the code. In the log, displays the time since the start of the request that this point was reached.</li>
<li><code>bench_measure</code> — takes a "label" argument and block of code. Surrounds the block with bench_marker logging.</li>
</ul>
<p>You can pass a few flags to <code>bench_measure</code> — <code>:skip</code>, which does not execute the block at all, and <code>:echo</code>, which returns the string result of the block rather than concatenating it to the template output (and is therefore only really useful in helpers).</p>
<p><code>bench_marker</code> takes a hash of options, although only one option is currently checked — <code>:prefix</code>, which lets you change the text that precedes the timestamp in the logs.</p>
<p><em>Note</em>: like most logging, benchmarking only displays in development logs.</p>
Capistrano for remotely manipulating sites and blueprints/changeblog/post/capistrano-for-remotely-manipulating-sites-and-blueprints/
2008-08-07T11:27:18Z
God<p>There's a bunch of existing rake tasks for operating on blueprints and sites -- pushing and pulling data, syncing templates, installing blueprints and sites, erasing blueprints and sites, et cetera.</p>
<p>For the last few months, to perform these operations on remote servers (production or staging), you've had to log into the server as the deploy user, and run the rake task with the correct environment argument.</p>
<p>Now there are Capistrano tasks that allow you to do these things on remote servers from the comfort of your local command-line. Here's the current list of available tasks -- run <code>cap -T</code> for an official list.</p>
<pre><code>cap site:data:pull
cap site:data:push
cap site:list
cap site:retrieve
cap site:templates:update
cap blueprint:install
cap blueprint:migrate
cap blueprint:uninstall
cap blueprint:upgrade:all
</code></pre>
<p>Each cap task takes the same arguments as its rake equivalent. Assuming you have set up your <code>config/hosts.yml</code> file correctly, you can invoke them like this:</p>
<pre><code>$ cap site:data:push domain=foo.org rails_env=staging
</code></pre>
<p>The <code>rails_env</code> determines which hosts the action is performed on. To save typing, you might want to set up the following bash aliases:</p>
<pre><code>alias pcap='RAILS_ENV=production cap'
alias scap='RAILS_ENV=staging cap'
</code></pre>
<p>Then you can run the same command more succinctly:</p>
<pre><code>$ scap site:data:push domain=foo.org
</code></pre>Rake tasks for creating new blueprint modules/changeblog/post/rake-tasks-for-creating-new-blueprint-modules/
2008-08-07T11:01:21Z
God<p>Until recently, you used the <code>script/generate</code> task to create new blueprint modules. Now that blueprints are stored in a separate repository, however, this approach has been deprecated in favour of a rake task that not only generates the requisite files and directories, but imports them into your blueprint repository, and checks them out for you.</p>
<p>You can learn about the rake tasks using the <code>-D</code> describe switch:</p>
<pre><code>$ rake -D blueprint:create
rake blueprint:create
Generate a new blueprint, checking it into a blueprint repository.
Arguments:
CODE - the blueprint code for the new blueprint
ACTIONS - string list of actions (white-space separated) for which to
create templates and controller actions.
rake blueprint:create:inherit
Generate a new blueprint inheriting from an existing blueprint, checking
it into the selected repository. Arguments:
CODE - the blueprint code for the child blueprint
PARENT - the blueprint code for the parent blueprint
</code></pre>
<p>So, for example, to create a 'Directory' blueprint:</p>
<pre><code>rake blueprint:create CODE=dir ACTIONS="index list item alphabetical by_publication_date"
</code></pre>
<p>Or to extend the existing 'Gallery' blueprint to handle videos:</p>
<pre><code>rake blueprint:create:inherit PARENT=gly CODE=vidgly
</code></pre>The hosts.yml file/changeblog/post/the-hosts-yml-file/
2008-08-07T10:54:15Z
God<p>This is a fairly major change, and requires some explanation.</p>
<p>As Blueprint is now being used by developers other than Inventive Labs, anyone might potentially want to create custom blueprint modules. Previously these were all in the core Blueprint repository; this update has moved them into separate repositories. The 'Page' and 'Search' blueprint modules are the only ones that come with Blueprint core. The rest of the core modules have been moved to <code>http://canister.inventivelabs.com.au/blueprints/core</code>.</p>
<p>You can add your own repository for custom blueprints. The mechanism for this is the new <code>config/hosts.yml</code> file, which replaces Rails' built-in <code>database.yml</code> file. You'll need to create this file -- you can base it off the <code>hosts.sample.yml</code> file in the same directory. Define your site and blueprint repositories (you should probably retain the 'core' blueprints repository), and set up your databases as you previously did for databases.yml.</p>
<p>Once this is done, you need to follow a one-off upgrade path:</p>
<pre><code>rm -rf app
svn up
rake blueprint:upgrade:all
</code></pre>
<p>One of the benefits of this change is that you <em>no longer</em> need to enter the 'Repository root' for a site when running <code>rake site:retrieve</code>.</p>Asset captions/changeblog/post/asset-captions/
2008-07-15T10:39:45Z
God<p>The 'Bluedown' text formatter has had an upgrade, providing marked-up caption text for images inserted into text fields.</p>
<p>As you know, you can insert an image into text with the following syntax:</p>
<pre><code>[[example]]
</code></pre>
<p>Which results in markup like this:</p>
<pre><code><img alt="Example" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/4068c115/example.jpg" title="Example" />
</code></pre>
<p>There are a bunch of options you can add to the asset tag, such as:</p>
<pre><code>[[example|class=left,size=thumb]]
</code></pre>
<p>Which modify the resultant HTML in certain ways:</p>
<pre><code><img alt="Example" class="left" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/4068c115/example_thumb.jpg" title="Example" />
</code></pre>
<p>Just added is the ability to do captions, by attaching parenthesised text to the end of the asset tag:</p>
<pre><code>[[example]](This is a free markdown area, until the next closing parenthesis not
preceded by a backslash. So this won't close the caption: \) but this *will*: )
</code></pre>
<p>Which gives markup like the following:</p>
<pre><code><div class="captioned">
<img alt="Example" src="http://blueprint.inventivelabs.com.au:80/static/files/assets/4068c115/example.jpg" title="Example" />
<blockquote><p>This is a free markdown area, until the next closing parenthesis not
preceded by a backslash. So this won't close the caption: ) but this <em>will</em>: </p></blockquote>
</div>
</code></pre>
<p>That is, the image tag is enclosed in a div tag with the class <code>captioned</code>, which also contains a blockquote containing the marked-up caption text. You can then style this however you like with CSS.</p>