Summary: How to build a blog system with pagelists
Version: 26 October 2005
Prerequisites: Requires at least PmWiki version: 2.1.beta; last tested on PmWiki version: 2.0.3
Maintainer: MarcioRPS
Categories: Blog, PageList, MarkupOnly


Can I make a blog just using the PageList Directive?


Well, of course.

The pagelist directive is very flexible (and getting better every day!). Therefore, there are many different ways to use it to achieve what would stand for a blog. A general idea will be described first, and below many other ideas about how to deviate from this strategy. HansB has joined those ideas in an experimental blog bundle.

The idea is that entries in the log are different wiki pages. We use the pagelist directive to make beautifull presentations of it, from a blog page containing the full text of the last entries to a sidebar containing just the entries. The blog entries all belong to a group called BlogGroup.

This invocation:

(:PageList group=BlogGroup fmt=#include list=normal count=10 order=-ctime :)

will be replaced by PmWiki with the complete text of the last 10 entries created (not only modified) in the BlogGroup group. For this to work you need to add the following custom fmt=#include to Site.PageListTemplates:


This format includes whole pages, with titles as links to the pages, separated by a horizontal rule underneath each page's content. An edit link appears if authorised as editor.

(:if auth edit:)
(:include {=$FullName}:)
(:if equal {>$Group}:)
(:title {$Title}:)(:if:)

Note: {$Title} is added to the end to preserve the page title, so it will not be replaced by any title given with the included pages. PmWiki may change this in future to preserve titles automatically. So this is a bit of a hack here to overcome a present limitation in PmWiki.


Pagelist of spaced blog titles with date stripped for sidebar.

[[#blogtitles]](:if equal {<$Group}:)
* [[{=$Namespaced}]]
(:if equal {>$Group}:)

You can alter this to fit many purposes. For example, change count=10 in the pagelist to the amount of entries you want listed (and remember count can have negative values). You can find more info on how to tweak those values in PmWiki.PageLists and Site.PageListTemplates .

And that is the format for a list of only the entries' names, best suited for a SideBar or listing page:

(:PageList group=BlogGroup fmt=#blogtitles list=normal count=10 order=-ctime :)

The format below includes just the first paragraph of each page in a pagelist. Just start each blog entry with a introduction/teaser.


(:include {=$FullName} para=1:)
!!!!Full article [[{=$FullName}|[+{=$Title}+]]]
(:if equal {>$Group}:)
(:title {$Title}:)(:if:)

(:pagelist group=BlogEntries order=-time fmt=#headerinclude count=5:)

Naming and placing of blog entries

If you do as explained above, all your entry-pages will be separated from everything else in their particular group. This way, their names are easy to read and understand.

You can add the blog group in the search exclude patterns so that your blog entries won't mess the rest of your wiki. If you have many blogs you can specify a prefix for the blog groups and add the prefix to the search patterns.

Another option is making all your blog entries have a name that start with a date. For example: 2006-02-03-todayIEditedTheCookbook. This have many advantages:

  • it is much faster for the sorting (order=ctime forces pmwiki to open all the files)
  • allows you to create pages not refering to the moment you are creating them
  • it might make for better understandability
  • it might allow you to avoid having a blog group, instead leaving the blog entries in a personal group and sorting them through a list= argument to the pagelist.

Then each new blog entry must be named beginning with the date, always in the same format, and with the year first, then month, then day, etc, as specifically as one wants. For example, 2005-10-25-ThisIsMyFirstEntry, or 197910 or something of the like. Remember to stick to a same format. This is very important so that the ordering of the pages will be correct.

At first, you will have to write those names in the address bar of your browser, and they will NOT appear as WikiWords. This can be changed (see below).

If the blog entries all start with the date, you can create a search pattern that only show blog entries. Then when you use list=dates inside your pagelist directive you exclude other pages. To to this, use the following code:

$SearchPatterns['dates'][] = '/\.[0-9]{4}/';

Making all entries alike

If you feel that your blog entries need to share a common style, you can set an Edit Template for the group to try and make all entries follow a common format.

Utilities for a better blog experience

Add the following code to config.php, or install blogdate.phpΔ by copying the script to the cookbook directory and adding to config.php include_once("$FarmD/cookbook/blogdate.php");

 /* page variables defined in blogdate.php */ 
# add page variable {$Today}, formats today's date as yyyy-mm-dd
$FmtPV['$Today'] = 'strftime("%Y-%m-%d", time() )';

# add page variable {$BlogDate}, displays as page creation date
$FmtPV['$BlogDate'] = 'strftime("%Y-%m-%d", $page["ctime"])';

# add page variable {$BlogTitle}, displays as spaced name with date stripped off
$FmtPV['$BlogTitle'] = 'StripDate($pagename)';
function StripDate($pagename) {
    $sd = preg_replace("/[^.]*\.([\d\-]*)(.*)/e","'$2'==''?'$1':'$2'",$pagename); 
    $BlogTitle = AsSpaced($sd);
    return $BlogTitle;

This adds several tools:

  • a {$Today} page variable which displays as today's date in the format yyyy-mm-dd
  • a fmt=#blogtitles format option for pagelist, which strips away the date part of the page names, to give nice lists of names only. The pagelist template is described below.
  • a {$BlogTitle} page variable which displays the pagename without the date part (if there is more than just the date in the page name) and spaces the words.
  • a {$BlogDate} page variable which displays the page creation date in the format yyyy-mm-dd.

You can use (:title {$BlogTitle}:) in the page. Best include this in an Edit Template to be used for all blog pages. {$BlogTitle} is defined as a custom page variable in blogdate.phpΔ. It strips the date part from the name and spaces the name. The blog pages will appear in pagelists also with this stripped title. If there is no name part then the date part will remain as the page name.

The NewPageBoxPlus recipe allows you to creates a newpagebox which has today's date already in it as an initial value, and you just need to add the blog title. It creates new blog pages in group "Blog". Add the following markup somewhere to create a simple form for creating new blog pages:

(:newpagebox button=right label="New Blog Entry" size=40 base=Blog.HomePage value="{$Today}-":)


If you make a pagelist with the include format and it includes itself it might generate problems, akin to what happens when you put a mirror in front of another. (Maybe Pm stopped it from happening with the new pagelist, I'm not sure, but it used to give big problems...)



Well, I am not really counting this, but after the adoption of PagelistTemplates it should be at least 0.4

See Also



See discussion at BlogWithPageList-Talk

User notes? : If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.