2 column news and events page list template for concrete5
Hi all
I’ve been building the theme for a new concrete5 site, and the designers of the site specified a two-column, four-item news area on the homepage, showing news items in descending date order, in a Z shape. This is what the layout looks like:

concrete5′s pagelist block is the best thing for this job, but I wasn’t sure how to make it play such that (a) the news items would show in two columns, and (b) the items would be displayed in reverse chronological order, in a layout like this:
| 1 | 2 |
| 3 | 4 |
People tend to read text on a page in a F-pattern, moving across the top of the page (first row) before down the left-hand side. So it makes sense that news items should flow from top left to top right, down to bottom left then bottom right. More can be seen on Jakob Nielsen’s web usability site.
The problem is that in all the CSS implementations of columns that I know, the content in the vertical columns is set out one column at a time. In other words, items 1 and 3 in the table above are in one column, and 2 and 4 are in another. 1 and 3 must be pulled from the database and displayed before 2 and 4 are. Obviously that causes problems when you tell the pagelist block to order things by the most recent page, as for news items – it wants to spit out the pages in reverse chronological order (1,2,3,4), but to get the CSS and HTML to play ball you need the order to be 1,3,2,4. Here’s a depiction of the order vs layout problem:
| Column1 | Column2 |
| 1 | 2 |
| 3 | 4 |
How to get round this?
Well firstly, to get the columns working I’m using the code from Matthew James Taylor’s site. He has published numerous standards-compliant and cross-browser (phew) CSS-based layouts, and it’s fast becoming my defacto place to begin when trying to create anything but the most basic CSS layout. I used the 2 Column Double Page layout, but I think the principle will work whatever layout you choose – you just have to be methodical about the code that you insert into the layout to generate the page list.
Here is the (edited) CSS layout that I’m using. You can refer to the page over on Matthew James Taylor’s site for details on how to tweak his layouts (you have to be quite precise with pixel/percentage amounts in order to keep the layout looking right, so rather than detail that here I’ll leave that to him – he did create the layouts after all):
.colmask {
clear:both;
float:left;
width:100%;
overflow:hidden;
}
/* common column settings */
.colleft {
float:left;
width:100%;
position:relative;
}
/* 2 Column (double page) settings */
.doublepage { }
.doublepage .colleft {
right:50%; /* right column width */
}
.doublepage .col1 {
width:46%;
left:50%;
}
.doublepage .col2 {
width:46%;
left:54%;
}
This is a simple liquid two-column layout, with a 4% space between the two columns. Nice and clean. The corresponding HTML looks like this:
<div class="colmask doublepage">
<div class="colleft">
<div class="col1">
<!-- column 1 content -->
</div>
</div>
<div class="col2">
<!-- column 2 content -->
</div>
</div>
Now for the interesting part. As mentioned above, the first CSS column has to be populated first, therefore we need concrete5 to spit out items 1 and 3. After that, the second CSS column needs populated with items 2 and 4.
The way to achieve this is to create a couple of loops, one displaying items 1 and 3 from the array of possible pages, and the other displaying items 2 and 4 from the array. It’s pretty basic PHP, but it works!
The code for column one looks like this:
<?php
for ($i = 0; $i < 3; $i+=2 ) {
$cobj = $cArray[$i];
$title = $cobj->getCollectionName();
?>
<h3><a href="<?php echo $nh->getLinkToCollection($cobj)?>"><?php echo $title?></a></h3>
<div class="news_summary">
<?php
if(!$controller->truncateSummaries){
echo $cobj->getCollectionDescription();
}else{
echo $textHelper->shorten($cobj->getCollectionDescription(),$controller->truncateChars) . ' <span class="newsmore"><a href="' . $nh->getLinkToCollection($cobj) . '">more</a></span>';
}
echo '<br /><div class="newsdate">Posted ' . $cobj->getCollectionDateAdded('j F Y');
?>
</div>
<?php
}
?>
| Column1 | Column2 |
| 1 | |
| 3 |
The crucial bit is the beginning of the for loop on line 2. $i equals 0 on the first iteration of the loop. PHP arrays by default begin at 0 instead of 1, so the first item in the array is item zero, the second is item one, the third is item two and so on. On loop iteration 1, therefore, we display the first item in the array (item 0, which corresponds to the first page which matches the page list rules set in the page list block interface). $i is then incremented by 2 ($i+=2 is shorthand for $i = $i + 2). So $i now equals 2 (0+2). The loop therefore spits out the third item in the array, which corresponds to the third page matching the block’s rules. Excellent. We therefore have the first and third pages appearing in our first CSS column. Note that because the loop will only execute while $i is less than 3, it means that it will never get beyond two iterations, because on the third iteration $i would equal more than three.
Here is the code for the second column:
<?php
for ($i = 1; $i < 4; $i+=2 ) {
$cobj = $cArray[$i];
$title = $cobj->getCollectionName();
?>
<h3><a href="<?php echo $nh->getLinkToCollection($cobj)?>"><?php echo $title?></a></h3>
<div class="news_summary">
<?php
if(!$controller->truncateSummaries){
echo $cobj->getCollectionDescription();
}else{
echo $textHelper->shorten($cobj->getCollectionDescription(),$controller->truncateChars) . ' <span class="newsmore"><a href="' . $nh->getLinkToCollection($cobj) . '">more</a></span>';
}
echo '<br /><div class="newsdate">Posted ' . $cobj->getCollectionDateAdded('j F Y');
?>
</div>
<?php
}
?>
| Column1 | Column2 |
| 2 | |
| 4 |
Just a tiny tweak to the for loop here. Now we start with $i equalling 1, which refers to the second item in the array (remember the array’s items start at 0, therefore 1 is the second item – 0,1,2,3). Once that’s displayed, $i is again incremented by 2, so it now equals 3 (its original value of 1, plus 2). Item 3 in the array is in fact the fourth item in that array (0,1,2,3…), which corresponds to the fourth page. Again, because the loop will only execute while $i equals less than 4, it will only iterate twice, because on the third iteration $i would equal 6.
Stick the HTML and PHP together and you get this:
<div class="colmask doublepage">
<div class="colleft">
<div class="col1">
<?php
for ($i = 0; $i < 3; $i+=2 ) {
$cobj = $cArray[$i];
$title = $cobj->getCollectionName();
?>
<h3><a href="<?php echo $nh->getLinkToCollection($cobj)?>"><?php echo $title?></a></h3>
<div class="news_summary">
<?php
if(!$controller->truncateSummaries){
echo $cobj->getCollectionDescription();
}else{
echo $textHelper->shorten($cobj->getCollectionDescription(),$controller->truncateChars) . ' <span class="newsmore"><a href="' . $nh->getLinkToCollection($cobj) . '">more</a></span>';
}
echo '<br /><div class="newsdate">Posted ' . $cobj->getCollectionDateAdded('j F Y');
?>
</div> <!-- col1 end -->
<?php
}
?>
</div> <!-- colleft end -->
<div class="col2">
<?php
for ($i = 1; $i < 4; $i+=2 ) {
$cobj = $cArray[$i];
$title = $cobj->getCollectionName();
?>
<h3><a href="<?php echo $nh->getLinkToCollection($cobj)?>"><?php echo $title?></a></h3>
<div class="news_summary">
<?php
if(!$controller->truncateSummaries){
echo $cobj->getCollectionDescription();
}else{
echo $textHelper->shorten($cobj->getCollectionDescription(),$controller->truncateChars) . ' <span class="newsmore"><a href="' . $nh->getLinkToCollection($cobj) . '">more</a></span>';
}
echo '<br /><div class="newsdate">Posted ' . $cobj->getCollectionDateAdded('j F Y');
?>
</div>
<?php
}
?>
</div>
</div>
Save the above into a new page list template in your /blocks/page_list/templates/ folder, then you can apply it using the Custom Templates option on the block menu (shown below). Add the css above into your theme’s css file and you should be good to go.

In the code above I’ve left in some cosmetic additions of my own, for example the date on which the item was posted, and a little ‘more’ link at the end of the truncated summary. Obviously you can tweak the css styles of h3 and news_summary to your heart’s content, or add in other styles to get the look you want.
