Customizing Graffiti CMS, part III

(In which I continue taking apart a Wordpress theme to make it work with Graffiti. Part I. Part II. Part IV. )

Last time I'd set up the layout.view file and completed it by adding the @childcontent statement. Now I need to think about the other two main view files, index.view and post.view, the ones that will supply the child content.

The index.view file is possibly the easiest at this stage, since we started out with analyzing the equivalent PHP file from the Chronicles theme.

The index.view file is meant to display a list of posts. This list could come from a search, from a category list, from a tag list, and so on. No matter what the source, the view must display the post title, date, author, category, tags, and the first few words from each post. The way Graffiti works is that the list will have a maximum of 10 posts in it, and so we shall need to consider the paging facilities in Garffiti since after a while it's likely that there will be more than 10 posts to display.

So, all in all, there's a lot to consider.

The way I constructed the layout.view file, the content view files are responsible for deciding whether they want to display none, one, or both sidebars, and then displaying them. The sidebars are rendered by Chronicles as

<?php include (TEMPLATEPATH . '/sidebar1.php'); ?>

So, all we need to do is (roughly) the same for Graffiti:

$macros.LoadThemeView("sidebarleft.view")

After changing the PHP code in sidebar1.php to sidebarleft.view I had this:

   1: <div id="sidebar1">
   2:     <div id="sidebar1_top"><!-- Hack for IE --></div>
   3:     <ul>
   4:         $macros.LeftSideBar("%{beforeWidget='<li class=\"widget\">', afterWidget='</li>', beforeTitle='<h2>', afterTitle='</h2>'}")
   5:     </ul>
   6:     <div id="sidebar1_bottom"><!-- Hack for IE --></div>
   7: </div><!--end of sidebar1 -->

Similarly for the right sidebar:

   1: <div id="sidebar2">
   2:     <div id="sidebar2_top"><!-- Hack for IE --></div>
   3:     <ul>
   4:         $macros.RightSideBar("%{beforeWidget='<li class=\"widget\">', afterWidget='</li>', beforeTitle='<h2>', afterTitle='</h2>'}")
   5:     </ul>
   6:     <div id="sidebar2_bottom"><!-- Hack for IE --></div>
   7: </div><!--end of sidebar2 -->  

The nice thing about the $macros methods that render the sidebar is that you can specify the HTML tags that go around the widget "content" and around the widget titles. I'll talk at another stage how to write a sidebar widget.

Now we have some PHP code that iterates through the posts:

   1: <?php if (have_posts()) : ?>
   2: <?php while (have_posts()) : the_post(); ?>

Graffiti's Chalk language has a foreach loop construct which will nicely replace this. The loop has the following syntax:

   1: #foreach($post in $posts)
   2:   #each (this is optional since it’s the default section)
   3:        <!--text which appears for each item-->
   4:   #before
   5:        <!--text which appears before each item-->
   6:   #after
   7:        <!--text which appears after each item-->
   8:   #between
   9:        <!--text which appears between each two items-->
  10:   #odd
  11:        <!--text which appears for every other item, including the first-->
  12:   #even
  13:        <!--text which appears for every other item, starting with the second-->
  14:   #nodata
  15:        <!--Content rendered if $items evaluated to null or empty-->
  16:   #beforeall
  17:        <!--text which appears before the loop, only if there are items matching condition-->
  18:   #afterall
  19:        <!--text which appears after the loop, only of there are items matching condition-->
  20: #end

As you can see, this a very rich for loop, geared to producing rich visual displays of lists.

The $posts list id provided by Graffiti when the view is rendered. The $post variable is defined by us, and we can call it what we want. It'll be used within the loop to expose the various interesting properties of the post itself.

   1: $post.Body -- the body of the post
   2: $post.CreatedBy -- the user who created the post
   3: $post.Url -- the site's url to the post
   4: $post.Title - the title of the post
   5: $post.Published -- the date/time that the post was published
   6: $post.CommentCount -- the number of comments for the post

From these properties and from the Chalk foreach loop we can convert the PHP code and HTML formatting to a Graffiti view.

   1: #foreach($post in $posts)
   2:   #each
   3:     <div class="post" id="$post.id">
   4:  
   5:       <div class="date">
   6:         $post.Published.ToString("MMM dd yyyy")
   7:       </div><!--end of date -->
   8:  
   9:       <div class="post_title">
  10:         <h2><a href="$post.Url" rel="bookmark" title="$post.Title">$post.Title</a></h2>
  11:         <div class="posted">
  12:           Posted by $post.CreatedBy at $post.Published.ToString("h:mm tt")
  13:         </div><!--end of posted -->
  14:       </div><!--end of post_title -->
  15:  
  16:       <br clear="all" />
  17:  
  18:       <div class="tags">$macros.TagList($post.TagList)</div><!--end of tags -->
  19:  
  20:       $post.Excerpt("<p>", "</p>" ,"Read more...", 300)
  21:       
  22:       <div class="meta">
  23:         Filed under : $macros.CategoryLink($post.Category) | $macros.CommentUrl($post, "%{anchor='comments'}")
  24:       </div><!--end of meta -->
  25:     </div><!--end of post -->
  26:  
  27:   #nodata
  28:     <div class="post">
  29:       Sorry, there are no posts matching your request.
  30:     </div>
  31:   
  32:   #end

The code to add paging is simplicity itself, although to my taste a little too simple since we cannot change the text that will be shown when there is a previous or next page of posts (the text is hard-coded in Graffiti.Core.dll). The one and only parameter is the CSS class name for the div that contains the previous/next paging links.

$macros.Pager("navigation")

(UPDATE: Scott Watermasysk informs me in the comments below that there is an overload that does allow you to set the previous/next paging link text:

$macros.Pager(CssStyle, PreviousText, NextText)

I've altered the calls to paging in my view files.)

Next time, we'll look at the final piece of the theme conversion puzzle.


Posts on similar topics...

Share it: Digg It!  StumbleUpon  Reddit  Del.icio.us  NewsVine  Furl  BlinkList  Ma.gnolia  Technorati

3 Responses

  • Tue 02 Dec 2008
  • 6:36 AM
  •  avatar #1

Scott Watermasysk said...

Hi Julian,

Great series of posts. We will improve on the documentation.

For the pager, there is a $macros.Pager overload which lets you pass in the previous/next text: $macros.Pager("cssName", "previous", "next)

If you wanted even more control, you could potentially write a custom extension which calls Graffiti.Core.Util.Pager(...) as well.

HTH,

Scott

  • Sun 07 Dec 2008
  • 8:09 PM
  • julian m bucknall avatar #2

julian m bucknall said...

Scott:Thanks for the hint: I've already applied it -- and updated the post.

Cheers, Julian

  • Fri 01 Jan 2010
  • 6:52 AM
  •  avatar #3

zhaojc said...

where is the similar topics module?

Leave a Response

About Me

I'm Julian M Bucknall, the M because it's my middle initial and because I and the other Julian Bucknall (the movie guy) would like to differentiate ourselves.

I'm a programmer by trade, an actor by ambition, and an algorithms guy by osmosis. I write articles for PCPlus in my spare time, not that there's much of that.

Julian M Bucknall Apart from that, an ex-pat Brit, atheist, microbrew enthusiast, Pet Shop Boys fanboy, slide rule and HP calculator collector, amateur photographer, Altoids muncher.

DevExpress

I'm Chief Technology Officer at Developer Express, a software company that writes some great controls and tools for .NET and Delphi. I'm responsible for the technology oversight and vision of the company.

The OUT Campaign

The OUT Campaign

Validation

Valid XHTML 1.0 Transitional     Valid CSS!

Bottom swirl

Archives

March 2010 (8)
SMTWTFS
« Feb  
123456
78910111213
14151617181920
21222324252627
28293031

Like this Archive Calendar widget? Download it here.

Search

Google ads

My Tweets

Bottom swirl