How to build a news page
#1
Posted 09 January 2011 - 04:50 PM
http://www.swindells...ls-accountants/
Latest news first with a headline being a link to the full story perhaps. It would need a backlink to the last page of pagination and a prev/next to the other articles. Intelligent enough so that the prev/next finish at the end/start of all news pages.
#2
Posted 10 January 2011 - 10:46 AM
1. news_index.php
2. news_story.php
You can call those templates above whatever you want, but just note that we'll use a separate template for news stories and news items. Your news_story template will contain the following fields:
1. title
2. date (date)
3. body (textarea)
And it's markup might look like this (excluding headers, footers, etc.):
/site/templates/news_story.php:
<h1><?=$page->title?></h1> <div id='bodycopy'> <?=$page->body?> </div>
Not much action there. Your news_index is where most of the action will happen. In Admin > Setup > Templates > news_index > Advanced, check the box for "Page Numbers" to turn them on. Save.
Here is what the code in your news_index.php might look like:
/site/templates/news_index.php:
<h1><?=$page->title?></h1>
<?php
// start the news stories list
echo "<ul>";
// get the stories for this page
$stories = $page->children("limit=4, sort=-date");
// note if you set the stories to sort by date descending on the /news/ page
// in the admin, then you can omit the "sort=-date" above.
// cycle through each story and print it in a <li>
foreach($stories as $story) {
echo "
<li><a href='{$story->url}'>{$story->title}</a>
<p><strong>Date:</strong> {$story->date}</p>
{$story->body}
</li>
";
}
echo "</ul>";
// get values for our placemarker headline
$start = $stories->getStart();
$end = $start + count($stories);
$total = $stories->getTotal();
$num = $input->pageNum;
$lastNum = ceil($total / $stories->getLimit());
// output the placemarker headline
echo "<h4>Showing $start - $end of $total Article/s | Page $num of $lastNum</h4>";
// output pagination links
echo $stories->renderPager();
Lets say that you don't want the pagination links that renderPager produces, you can always modify it's output by passing params to it. See the page about pagination here:
http://processwire.c...rkup-pager-nav/
But if you want your literal "previous" and "next" buttons like on your site, then you'll want to insert your own logic to do that. Something like the next example.
Note I'm reusing the vars I set in the previous example here for brevity. This snippet would replace the renderPager() method in the previous example.
<?php
// make the previous link
if($num > 2) $prevLink = "./page" . ($num-1);
else if($num == 2) $hrefLink = "./"; // page 1
else $prevLink = "./page" . $lastNum; // last page
// make the next link
if($num >= $lastNum) $nextLink = "./"; // page 1
else $nextLink = "./page" . ($num+1);
// output the prev/next links:
echo "<p><a href='$prevLink'>Previous</a> <a href='{$nextLink}'>Next</a></p>";
Disclaimer: the examples on this page are just written off the top of my head and are not actually tested examples. You'll likely have to tweak them. In particular, you may have to add or subtract 1 in a few places to get the right numbers. If you end up adapting this, please let me know of any errors I have here so that I can correct them.
#4
Posted 11 January 2011 - 12:11 PM
Using a 'summary' field
I think it's more common on this type of page that you would display a summary of the news story rather than the whole news story... and then link to the full news story. To display a summary, you could have a separate 'summary' field in your template, which would be just a regular textarea field where you would have a 1-2 sentence summary of the article. And you would display this 'summary' field rather than 'body' field in the news_index template.
If you wanted to autogenerate a summary from the 'body' field (rather than creating a new 'summary' field), you could just grab the first sentence or paragraph of the body and use that as your summary. This is how I usually do something like that:
<?php
// make our own summary from the beginning of the body copy
// grab the first 255 characters
$summary = substr($story->body, 0, 255);
// truncate it to the last period if possible
if(($pos = strrpos($summary, ".")) !== false) {
$summary = substr($summary, 0, $pos);
}
That's a really simple example, and you may want to go further to make sure you are really at the end of a sentence and not at an abbreviation like "Mr."In the example that Moondawgy posted, it makes sense to autogenerate a summary (if he needed it). But in other cases, the 'body' can be quite long (and take up a lot of memory), and it makes more sense to maintain a separate summary field if you have to keep a lot of pages loaded at once. This is really only an issue once you get into hundreds of pages loaded at a time. It's not an issue in these examples, but I just wanted to point it out.
Autojoin
Using the 'autojoin' optimization can increase performance on fields that get used a lot. Not using it can reduce the page's memory footprint. What is more desirable in each instance depends on your situation. In this news section example, the date and body fields would benefit from having 'autojoin' turned ON. See this page for an explanation:
http://processwire.c...topic,32.0.html
#5
Posted 30 August 2011 - 12:56 PM
I am trying to build a news page like Ryan described in his first example above, but i cannot get the pagination to work - it is not shown (see attached file)
I have the both required modules installed (they were already installed in PW 2.1).
Any idea what could be wrong? I have read about pagination in the doku and the forum, tried different things out - but the pagination does not appear...
Kind regards,
Christian
#6
Posted 30 August 2011 - 01:20 PM
If this doesn't resolve it, please post a code example or attach your entire template file if possible.
#7
Posted 30 August 2011 - 02:51 PM
Another thing that appeared is that the date shows always " 31/12/1969 19:00" if i doesn't input anything. I am using the datepicker and have set "use todays date" to active. Any idea what could bw wrong?
#8
Posted 30 August 2011 - 06:31 PM
For the 1969 date, that's the first value a date can have in a unix timestamp, so it basically means there is no date set. I'm guessing that the "default to today's date" was added sometime after the pages with 1969 were created. Either that, or that the field was added to a template but a date wasn't set in all the pages. The default is only set when you edit a page, so you would have to edit and save a page for it to pull in that default if it didn't have it before. In your case, what you may want to do is skip over the fields that don't have a date set:
if(!strpos($page->date, '1969')) {
// output your date
}
I'm trying to think of ways to avoid this problem from the core. Perhaps I should have PW return blank, rather than a formatted date, when the timestamp value is 0.
#9
Posted 30 August 2011 - 07:03 PM
BTW: After a few days testing around with PW i have to say that i am so happy that i have found this great system - i have tried out so many CMSs in the past few years and after i have spent few days now again with searching for a flexible system which supports custom fields i cannot think of any other system which fits my needs better!
Thank you very much for that great peace of software!
---
And although i knew already about the flexibility, again and again i am impressed how flexible and well-though-out this CMS is: i just discovered the template setting "List of fields to display in the admin Page List" - that will help my clients to work with the news-section much more comfortable...
#11
Posted 30 August 2011 - 08:30 PM
I have no doubt that you will!I will do my best to make sure it keeps getting better and better.
I have another little question...
In the news-template i have set the news to be sorted by date:
$stories = $page->children("limit=3, sort=-date");
If two articles are created the same day the last created is placed below the first created. I only found the solution to set the sort field on the page settings to created, but then this setting will be overwritten by the template.
Is there a possibility to set two parameters in the template (date and created)?
Another thing is that i wondered why "date" is not shown in the sort field - is this changed in PW 2.1? I just ask because you commented the code above:
// note if you set the stories to sort by date descending on the /news/ page
// in the admin, then you can omit the "sort=-date" above.
---
Ok, got it - i just made a mistake when i tried to add "-created" to the template, i did it like this:
$stories = $page->children("limit=3, sort=-date,-created");
but i had to do it like that:
$stories = $page->children("limit=3, sort=-date, sort=-created");
So now its working fine. Would maybe be a nice thing, if the sort field in the settings would allow multiple sort parameters too, or not? But as we can sort pages in the template it seems to be just an addition that you can set the sort field in the page settings - or are there any scenarios where it's better to use the page setting to sort them?
Ah, and i still couldn't find out why "date" is not shown there.
#12
Posted 30 August 2011 - 09:57 PM
Multiple sort parameters in your selector are just fine, and ProcessWire supports this as long as those fields are 'autojoin'.
It also sounds like you may need to add a time component to your 'date' custom field, so that you can sort by two entries in the same day. PW supports this, but you have to include time codes in your date input format, i.e. "dd-mm-yy H:i" where "H:i" is the time component (hours and minutes). (If you need them, here are the full set of date and time codes used by PW: http://www.php.net/m...nction.date.php).
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users












