Customizing the Blog

Modifying the Basic Blog to Use a Custom Item Type

These notes follow the May 2012 design partner webinar. By the end of May, we will be updating our SmartThemes so any newly created sites will already have these changes.

Convert to Custom Taxonomy and Item Type

  1. Start with new Basic site (or any site with our standard blog system).
  2. Create a new flat taxonomy called blog_tags.
  3. Create a new database item type named blog_post. Enable whatever standard fields you want: probably Author, Body, Excerpt, Published-At, Draft, and Icon. Add a custom field of type taxonomy, with the name blog_tags. Enter blog_tags!* in the options field. The ! makes this an autocomplete field, instead of picker, and the * allows multiple tags to be assigned to one post.
  4. Edit each of the blog pages, changing type="Posts" to type="blog_post". This sets them all to use the new custom item type.
  5. Edit each of the blog snippets to replace Posts with blog_post and tags with blog_tags.
  6. Add the config setting ui.admin.menu.disable and set the value to Blog Posts to hide the built-in blog posts from the control panel menu.

At this point, you should have the blog fully converted to a custom item type and custom taxonomy. You can then add custom fields to the blog_post item as desired.

Switching to Custom URLs

Now you can convert the blog posts to use URLs that don't have database IDs in them.

Enable the two fields at the end of the standard fields section in the blog_post custom item type definition (permalink_on and permalink_name).

Edit the post item page. Below the tabbed content area, choose Blog Post in the Linked Custom Item Type picker. In the Custom Item ID Pattern field, enter perma_link_on/perma_link_name.

In all of the blog pages and snippets, anywhere there is a link to a post page, replace <w:path url='post' /> with:

post/<w:perma_link_on />/<w:perma_link_name />

Adding a Tag Cloud

Download the Tag Cloud jQuery plugin and upload it to the Files area. We put it in a folder named "js".

Create a snippet called "tag_cloud" and put this code in it:

<h3>Tag Cloud</h3>
<div id='tag_cloud' style='margin-bottom:15px'>
    <w:taxonomy:each name="blog_tags">
      <!--  if the tag contains any posts:  -->
      <w:if_items taxonomy='current' type='blog_post'>
        <a href='<w:path url="/blog-tag" />' rel="<w:kb:item:count taxonomy='current' type='blog_post' />"><w:name /></a>               
      </w:if_items>
    </w:taxonomy:each>
</div>

<script src="/js/jquery.tagcloud.js"></script>
<script>
  $.fn.tagcloud.defaults = {
    size: {start: 12, end: 24, unit: 'px'},
    color: {start: '#999', end: '#111'}
  };
  $(document).ready(function() {
    $("#tag_cloud a").tagcloud();
  });
</script>

Include this snippet wherever you want, perhaps in the right region of all blog-related pages.

Create Archives by Month Picker and Page

Add a snippet named "archives_by_month" and put the following code in it:

<h3>Older Posts by Month</h3>

 <p id="blog-selector">
   <w:year_month_count_widget type="blog_post" outer_open="<select>" outer_closed="</select>" item_open="<option value='/blog-by-month/%Y/%m'>%B %Y (%count)" item_closed="</option>" fill_gap_years="false" fill_gap_months="false" inner_first_item="<option value=''>--Select--</option>" />
</p>

<script>
  $(document).ready(function(){
    $("#blog-selector select").change(function(){
      location.href=$(this).val();
    });
  });
</script>

Include this snippet wherever you want, perhaps in the right region of all blog-related pages.

Now you need to create the blog-by-month page to which this links. Create a new page with blog-by-month for the slug. Put the following code on the page:

<p><a href='/bp/blog'>< Return to Blog Home</a></p>

<w:kb:item>
  <w:paginate by='published_at desc' limit='10' page='auto' type='blog_post' condition="published_at>={{path-year}}-{{path-month}}-1&&published_at<{{path-year}}-{{path-month}}-1 + 1.month">
    <w:pagination_widget />
    <w:each >
      <div class='blog_article'>
        <w:unless condition='icon.blank?'><img src='<w:icon  rendition="thumb"  />' class='listing-thumb'  alt='' /></w:unless>
        <h3 class='article_title'><a href="post/<w:perma_link_on />/<w:perma_link_name />"><w:name /></a></h3>
        <p class='byline'>Posted <w:published_at format='%B %e, %Y' /> 
        <w:unless condition='author.blank?'>by <w:author /> </w:unless>     
        <w:if_comments><a href="post/<w:perma_link_on />/<w:perma_link_name />#comments"><w:comment_count /> comments</a> </w:if_comments></p>
        <p><w:description /></p>
        <p><a href="post/<w:perma_link_on />/<w:perma_link_name />">Continue reading</a></p>
      </div>
    </w:each>
    <w:pagination_widget />
  </w:paginate>
</w:kb:item>

Below the content tabs area, set the Page Type to "Blog Archive".

Set Up RSS Feed

Go to Structure > Feeds & XML Files and edit blog.xml.

Change type="Posts" to type="blog_post".

Change the two instances of <w:path url="default" /> to /post/<w:perma_link_on />/<w:perma_link_name />.

Add the RSS autodiscover tag to the html_head snippet, if it isn't already there:

<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="http://<w:account key='domain' />/blog.xml" />

You may want to set up your feed with Feedburner, which provides additional formatting of your feed, provides you with analytics, and allows you to inject ads in it if you want. If you do so, then you'd replace the href attribute in the autodiscovery tag above with the URL for the feed at Feedburner.

You can also get from Feedburner the code for a "subscribe by email" form that you can place on the site. Feedburner will then send anyone who signs up an email each time the feed is updated.

You may want to put an RSS icon on the page and link it to your feed (either the local feed or Feedburner's version).