(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.
3 Responses
#1 Scott Watermasysk said...
02-Dec-08 6:36 AMHi 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
#2 julian m bucknall said...
07-Dec-08 8:09 PMScott:Thanks for the hint: I've already applied it -- and updated the post.
Cheers, Julian
#3 zhaojc said...
01-Jan-10 6:52 AMwhere is the similar topics module?
Leave a response
Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.
_emphasis_
**strong**
[text](url)
`IEnumerable`
* an item
1. an item
> Now is the time...
Preview of response