13 - Implementing the Weblog Index Template

This post in the Building a Church Site on ExpressionEngine will cover how to use the weblog/index template for weblog, category, and archive views.  In order to do that I use several new-to-the-series EE tags, do some in-depth URL analysis, and then put EE segment variables and conditionals to work.

 
Download the EE Code for 13 - Implementing the Weblog Index Template

I had hoped to cover implementing both the weblog/index and weblog/comment templates. But after coding the index template I think there’s enough going on here to just focus on it for one chapter in this series.

Let’s work a bit backwards.  First—take a look at the completed weblog index on our in-process church site: http://church.train-ee.com/index.php/weblog/.

I want to point out a few things from a visual and functional perspective, then I’ll dive into the code and show you how they were done.

The Visuals
I had to do a fair amount of content styling because the template set we started with didn’t include a template suitable for a weblog.  I needed something with a larger main content area and a narrower secondary column for category and archive links.  The main styling need was subnavigation - which I used an option available at the list-o-matic as a basis for.  I also had to add styles for:

  • left-column header tags
  • right-column header tags (for when viewed in category or archive mode)
  • weblog post wrapper (to space out the posts)
  • weblog meta (for author, post date, and comment links)

Weblog View
This template serves up content in three ways; a regular weblog, a category page, and an archive page.  The weblog functionality is what loads by default - a pretty standard view with the latest post at the top, stamped with author name, when the entry was posted, and a link to a full entry.  Pagination links are at the bottom for accessing older entries.  Note the URL that the weblog function loads with (this will be important later):

http://church.train-ee.com/index.php/weblog/ 

Now is a good time to get familiar with EE’s URL Segment Variables.  In our case, when this template is loaded as a standard weblog with the url above, segment_1 contains “weblog” and all subsequent segments are empty.

Now click a pagination link, which returns a URL of:

http://church.train-ee.com/index.php/weblog/P3/ 

Now I have the same segment_1 value, but EE pagination has added a segment_2 value of “P3”.

OK - just sit on that for a moment while I work through the other main functions of this template….

Category View
The second function is as a category view.  Clicking on a category link in the left column:

  • Acts as a filter - refreshing the list of posts in the main content area, but only showing the posts belonging to that category
  • Displays a new header type in the right column content which pulls the category name and description
  • Highlights the left nav selection
  • Updates the browser title to add category information
  • Displays a new “Show All Posts” option at the bottom of the category list

Look at the URL structure again.  Clicking the “Church News” item in the left nav refreshes the page with a URL of:

http://church.train-ee.com/index.php/weblog/category/church-news/ 

Now I have a segment_1 value of “weblog”, a segment_2 value of “category” and a segment_3 value of “church-news”. 

Note that I’m getting textual category names in my URL’s and not ID#‘s because I have configured EE to do that.  That setting is found in the Control Panel under Admin >  Weblog Administration >  Global Weblog Preferences > Use Category URL Titles In Links?.

Category views also get paginated.  Clicking a pagination link in a category view refreshes the page with a URL like:

http://church.train-ee.com/index.php/weblog/category/church-news/P3/ 

Now I have a segment_4 value holding the EE-generated pagination code “P3”.

Archive View
The third function of this template is to act as a weblog archive - where users can select a month/year combination and get just the posts made during that year.  Clicking an archive link:

  • Acts as a filter - refreshing the list of posts in the main content area, but only showing the posts from that time period
  • Displays a new header type in the right column content which displays the month and year selected
  • Highlights the left nav selection
  • Updates the browser title to add month and year information
  • Displays a new “Show All Posts” option at the bottom of the list of archive choices

Once again let’s look at the URL’s that EE generates.  Clicking an archive link refreshes the page with a URL like:

http://church.train-ee.com/index.php/weblog/2008/05/ 

I now have a segment_1 value of weblog, segment_2 value of “2008” and a segment_3 value of “05”.

Pagination also applies to archive views.  Clicking a pagination link while in an archive view produces a URL like:

http://church.train-ee.com/index.php/weblog/2008/05/P3/ 

EE has again appended a pagination value to the segment_4 position.

So why I am I doing all this URL analysis?  Because, on the coding side, being able to “look up” at the URL and make decisions depending on what’s showing there is a very powerful feature of EE.  On this particular template it’s what enables the left navigation highlighting, the view-specific browser titles, the “Show All Posts” links, and the date headings that display after selecting an archive link.

Companion Files
Attached to this post zip file containing the companion files for this chapter. In the zip archive is the weblog/index template, stylesheets/style template, and embeds/main_nav template.  I’ll let you just load up the new stylesheet - I won’t be covering that in any specifics here.  The new main_nav template just makes the Weblog link active - so won’t cover that here either.  It’s the weblog/index template that we’ll need to spend some time on.

Setting the Page Title
So load up the weblog/index template in an editor and let’s start working through it.

The first bit of complexity in the template is figuring out the page title to pass to embeds/html_header.  Up until this point in this series all we’ve done is pass some static text. Now, however, we want the page title to reflect all the uses of this template - so showing when in weblog mode, category mode, or archive mode.  How to make that dynamic?  Here’s the code.

{embed="embeds/html_header" 

 
{!--The my_title value will always be used. --}
my_title
="Weblog 

 {!--The category heading tag will only kick in if this template is
      loaded with a category link. --}
{exp:weblog:category_heading weblog="
weblog"}
 | {category_name}
{/exp:weblog:category_heading} 

 {!--This code will kick in if an archive link has been clicked and will 
     display the month and year that the user selected. --}
{if segment_2 !="
category" AND segment_3!=""}
{exp:weblog:entries weblog="
weblog" limit="1
disable="
custom_fields|trackbacks|member_data|pagination|categories"}
{date_heading display="
monthly"}
 | Posts from {entry_date format="
%%Y"}
{/date_heading}
{/exp:weblog:entries}
{/if}
"

Hey…hey…don’t freak out on me quite yet…I know it looks like a lot.  Let’s work through it.  The code starts with the call to the embedded template as usual.  Next starts the building of the “my_title” variable.  The first bit is still the word “Weblog” - which I will always want regardless of how the template is used.  This takes care of the weblog use for the template.

Next is a new tag I haven’t covered yet - the Weblog Category Heading Tag.  The cool part about this tag is that it only loads if a template has been called with a category link.  When the template is loaded not in category mode, this tag will do nothing.  That takes care of the browser title for 2 of the 3 template uses. 

The last one is for when the template functions as a date-based archive.  How to handle that one?  Back to those URL segments again.  Looking at them I know when the weblog use is in place - either segment 2 is empty or it has a pagination value in it. I also know when we’re in category mode because segment_2 will always have the keyword of “category” in it.  And I know when we’re in archive mode because segment_2 will always have a value that isn’t category (the year) and segment_3 will always have a value (the month).

Knowing these things allows me to use another strong arrow in the EE quiver - ExpressionEngine Conditionals.  Using an EE conditional that analyzes the URL per our rule above lets me have code that only runs if an archive view has been selected.  In this case, the code contains a weblog:entries tag along with a date_heading variable pair that returns just the month and year combination for the subsequent entries returned by the parent weblog:entries tag.  This will serve to build the page title when the template is in archive mode.

OK….DEEP breath….

The rest of the template really just mimics most of the logic I just went through to determine the page title - so it should get easier from here.

Displaying Category Info
Now let’s be clear - I’m going through this template from top to bottom as it’s coded, but some of this functionality wouldn’t be triggered when the template is first rendered.  The category heading tag is just such a case - when weblog/index is loaded initially and the URL is empty past segment_1, this tag will do nothing.  This tag will kick in when a category link is clicked on and the page refreshes with category data in the URL.  Think of it as a dynamic tag smart enough to read the URL and know when it’s needed.

{!--The category heading tag will only kick in if this template 
    is loaded with a category link
. --}
{exp
:weblog:category_heading weblog="weblog"}
<div id="category_header">
<
h2>{category_name}</h2>
{if category_description}
<p>{category_description}</p>
{/if}
</div>
{/exp:weblog:category_heading} 

Overall the implementation here is very straightforward with just a simple conditional that looks to see if there is a category description and marks it up with paragraph tags if there is.

Main Weblog Entries Tag
Next up is the workhorse tag for this template - the main weblog:entries tag. 

{!--This is the main weblog:entries tag that will return individual blog posts.
 
The category links and archive links function as a filter on this tag. --}
{exp
:weblog:entries weblog="weblog" disable="trackbacks" paginate="bottom" limit="3"

The results returned by this tag are affected by the contents of the URL - if the URL has category data then only entries from that category are returned.  If the URL has a year and month value then the results this tag returns are filtered by that instead.  This is a really good example of when you absolutely need to have the weblog:entries tag be “dynamic” (and not set dynamic=“off”), as it’s that dynamic nature that lets this tag be so flexible with what it returns after looking at the URL contents. 

Just to be clear - the most notable thing about this particular use of the weblog:entries tag is what you aren’t seeing - which are parameters in the code forcing it to display a certain category or time frame.  The tag is just doing that by reading the URL.

Date Heading
Next up is the date_heading code again, this time putting the month & year content in the right column if an archive link was selected.  You’ll note that the conditional is the same used above in the page title code.  I’ve used a “monthly” setting because I should only get it once —the archive links have already told the main weblog entries tag (via the URL) to only return the entries for one month of one year.

{!--Using a conditional ensures the date heading 
    only displays 
if an archive link was selected. --}
{if segment_2 
!="category" AND segment_3!=""}
{date_heading display
="monthly"}
<div id="category_header">
<
h2>Posts from {entry_date format="%F %Y"}</h2>
</
div>
{/date_heading}
{
/if} 

Building Category Links
Above I looked at the category_heading tag and I mentioned that it was a reactionary tag—only displaying after a category link had been clicked on. So how are those category links created?  This template creates them in two places - within an individual weblog post and in the left column.

Individual weblog posts use the categories variable pair:

{categories} <a href="{path=weblog/index}">{category_name}</a> &nbsp;&nbsp;{/categories} 

The left navigation uses the Weblog Categories Tag:

{!--This tag will build the left-column subnavigation --}
{exp
:weblog:categories weblog="weblog" style="linear"}
<li>
<

 {
!--This conditional will cause the link to the currently-viewed category to be highlighted --}                                    
{if segment_3
==category_url_title}
class="active"
{/if}
href
="{path=weblog/index}">{category_name}
</a>
</
li>
{/exp:weblog:categories} 

The logic is essentially the same in both cases.  By building the links inside either one of those loops and using the Global Path Variable, EE will dynamically create the category links with the correct URL structure that the other code in the template needs to work with. Pointing these links right back at the weblog/index template is what enables this template to serve both functions.  You could create a template specifically for categories and link to that instead—but in the spirit of keeping this specific weblog implementation to as few templates as possible, I’ve just chosen the “index template as three functions” approach.

I’ll get back to the conditional here in a moment.

Building Archive Links
To drive my archives I’m using the Archive Month Links Tag:

{!--This tag will build the left-column archive subnavigation --}
{exp
:weblog:month_links weblog="weblog" limit="50"}
<li>
<

 {
!--This conditional will cause the link to the currently-viewed archive choice to be highlighted --}
{if segment_2
==year AND segment_3==month_num}
class="active"
{/if}
href
="{path=weblog/index}"{month}{year}
</a>
</
li>
{/exp:weblog:month_links} 

You’ll note the links use the same path=weblog/index value as the category links - this is how I’m telling EE to also re-use the weblog/index template for an archive view.  In this case, however,  EE is creating links with the year and month values that the main workhouse weblog:entries tag will see and use to filter its result set down to just the entries for one month.

Setting Left Column Navigation Active States
If you’ve played around with the rendered weblog you’ll note that the left navigation applies an active class to any category or archive link you select.  This is again done with a combination of segments and conditionals:

Category version:

{!--This conditional will cause the link 
   to the currently
-viewed category 
   to be highlighted 
--}                                    
{if segment_3
==category_url_title}
class="active"
{/if} 

The code compares the segment displaying the category_url_title to the link being generated and when it matches the active class will be applied to just that one list item.

Archive Version:

{!--This conditional will cause the link 
  to the currently
-viewed archive choice 
   to be highlighted 
--}
{if segment_2
==year AND segment_3==month_num}
class="active"
{/if} 

The archive version is a bit more complex because it needs to look at both segment_2 and segment_3 to handle both the year values and month values.

Show All Posts Links
The last added little feature on the page are the “Show All Posts” links that appear either in the category or archive lists if one of those options is selected.  Again, it’s segments and conditionals at work.

Category Version:

{!--This conditional will display a "show all" link 
   when template is loaded in a category mode 
--}                                    
{if segment_2
=="category"}
<li><a href="{path='weblog/index'}">Show All Posts</a></li>
{/if} 

Archive Version:

{if segment_2 !="category" AND segment_3!=""}
<li><a href="{path='weblog/index'}">Show All Posts</a></li>
{/if} 

Note that the logic used here is the same as elsewhere in the template—looking at segment_2 for something other than “category” and checking that segment_3 has anything at all.  If the conditions are met, the Show All Posts option is added to the unordered list.

Still With Me?
I think you can see now why I wanted to just focus on the weblog/index template.  There’s a fair amount going on here with different tags, segments and conditionals.  I do like the results, however, which seem highly functional from a user perspective while keeping our weblog implementation to two templates.

In the next chapter I’ll implement the single entry/comments template - and, since it’ll need some of the same left-column navigation as I built in this template, I’ll pull those sections of code out and create embedded templates from them instead.

 

Category Navigation

<< Previous Entry   

Next Entry >>

 

Previous Comments

Picture of andrew

by andrew

Date: Saturday, June 7th, 2008
Comment: #1

Mike, thanks for the warnings (many deep breaths required)—but it does make sense, and I can see the power in url segments and conditionals (awesome!).

Thanks for the gentle introduction, it’s certainly a step-up from embeds and embedded variables!

Love your work.

Cheers- A.

Mike Boyink

by Mike Boyink (Author)

Date: Tuesday, June 10th, 2008
Comment: #2

Thanks Andrew - good to know the articles are being read (not getting near the comment traffic on this series as the one I did on Boyink.com and not sure if it’s the subject nature or the registration requirement that’s causing that).

Picture of joshclark17

by joshclark17

Date: Tuesday, June 10th, 2008
Comment: #3

Don’t stop! We’re reading and waiting! It’s very helpful!

Picture of pcmeissner

by

Date: Sunday, July 13th, 2008
Comment: #4

Let me second that! I’m trying to get blog up and running on my church site, and this content is immensely helpful.

Picture of Mark

by

Date: Saturday, July 26th, 2008
Comment: #5

btw I just looked ahead to the next post and the comment by parsoncraig seems a very similiar issue. Just to let you know I definitely have categories set to use urls and the weblog is in separate template group. Thanks in advance.

Mike Boyink

by Mike Boyink (Author)

Date: Saturday, July 26th, 2008
Comment: #6

I can’t help if you don’t give me any clues.

What issue?  If it’s a URL issue then post the link that EE is generating.  Tell me the template names and template groups.  Tell me what you think should be happening.

Picture of bernietheone

by

Date: Saturday, October 11th, 2008
Comment: #7

Mike, i got problems with the subnav which points back to “/index.php/weblog/“, i didn’t work for me, th link always gets added to the url which sits already there instead of replacing it. If i used {path=weblog/index} instead it worked. Could it be that the reason is that my site & ee-install sits in a separate folder in the htdocs-Folder? And lastly, is there a reason not to use {path=weblog/index} for going back to “/index.php/weblog/“?.
Again: Thanks for your hard work and this mega-contribution to the ee.-community!

Bernd

Mike Boyink

by Mike Boyink (Author)

Date: Saturday, October 11th, 2008
Comment: #8

If it works - use it! ;)

You’ve just uncovered a bad habit of mine that I’m trying very hard to overcome - which is using path variables for links. 

When I started in EE I didn’t fully grok the value of pathing variables - and I still find myself coding links without them.

Definitely use them - and just for the reason you found here.  Using the path variables will neutralize differences in EE install locations, etc.

In fact I’ll update the code on this page to use them.

Picture of Amy Stoddard

by Amy Stoddard

Date: Monday, November 3rd, 2008
Comment: #9

I don’t know if anyone else had an issue with their hosting account, but when I got to this point in the tutorial my weblog kept registering “No Input File Specified.“  I found a solution to this on the EE forums.  My host is GoDaddy.  http://expressionengine.com/forums/viewthread/74436/

Mike Boyink

by Mike Boyink (Author)

Date: Monday, November 3rd, 2008
Comment: #10

Thanks for the heads up Amy.

Picture of Marcus Mucha

by Marcus Mucha

Date: Sunday, November 16th, 2008
Comment: #11

Thanks for this “big” post Mike. Especially for breaking this down piece by piece. I guess this is one of those templates that is a bit “deeper” than others, but with good reason.

Cheers!

Picture of parsoncraig

by

Date: Friday, January 2nd, 2009
Comment: #12

Mike,
In your book version of this, you may want to clarify what the location of the member profile of the author is supposed to be in the section of your code that says

By <a href=“http://www.train-ee.com/courseware/forums/member/{author_id}/“>{author}

.  I get the 404 error message:

Not Found

The requested URL /courseware/forums/member/1/ was not found on this server.

Obviously, the courseware/forums tag comes from your own setup, but I struggled to find the right url to point to. I wonder if you have the index.php file either renamed or designated as part of site_url. 

Ideally, I’d like to do two things:  1) go to the profile of the author, and 2) click on display all entries by that author.

This is what does that for me: {site_url}index.php/forums/member/{author_id}/

Mike Boyink

by Mike Boyink (Author)

Date: Friday, January 2nd, 2009
Comment: #13

Ah - that slipped through the cracks.

I’m not including forums on this site so it should be:

{url_or_email_as_author} 

Thanks for the tip!

Add Your Comment

Comment on this Post

  

Unless otherwise stated all content is © Michael Boyink of Train-ee.com & Boyink Interactive. Please don't steal - I've got kids to feed...