1) How do you get the "Next" page when one exists??
and
2) How do you get the URL to actually display? The code above literally puts in the words, "[previous url]" directly into the markup. We need the actual URL to display there.
I think the best way to do this would be to extend the Framework.PageList class, since it doesn't do any delegates... otherwise we would have to attach to each control that uses the PageList. But I'm not sure if it's possible to access the Head object to insert those strings while in there.
Thanks WallPhone. I actually did try it from the framework and wasn't able access the Head object successfully.. That's what prompted me to bump this again (sorry).
I'm just not understanding how everyone above said they were able to get this to work...
The page list is not a regular control, its just a class that builds a link list. Unfortunately, since the page list isn't invoked until the relevant control itself is rendered, the head is already rendered by the time this page list class gets executed.
Fortunately, the rel attributes are valid on regular <a links also...you may need to test to see if it works. This is what I came up with:<?php
/*
Extension Name: Rel Page List
Extension Url: http://lussumo.com/community/discussion/6529/pagination-and-meta-titles/
Description: Inserts appropriate rel attributes into the Vanilla PageList class
Version: 1.0
Author: WallPhone
Author Url: http://WallPhone.com/
*/
if (!defined('IN_VANILLA')) exit();
require_once($Configuration['LIBRARY_PATH'] . '/Framework/Framework.Class.PageList.php');
Class RelPageList Extends PageList {
// Builds a literal page list (ie. "previous next")
function GetLiteralList() {
$this->DefineProperties();
$sReturn = '<div class="'.$this->CssClass.'"';
if ($this->PageListID != '') $sReturn .= ' id="'.$this->PageListID.'"';
$sReturn .= '>';
$QSParams = $this->QueryStringParams->GetQueryString();
// Define the querystring
$iTmpPage = 0;
if ($this->PageCount > 1) {
if ($this->CurrentPage > 1) {
$iTmpPage = $this->CurrentPage - 1;
$sReturn .= '<a rel="prev" href="'.GetUrl($this->Context->Configuration,
$this->Context->SelfUrl,
'',
$this->UrlIdName,
$this->UrlIdValue,
$iTmpPage,
$QSParams)
.'">'.Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $this->PreviousText).'</a> ';
} else {
$sReturn .= Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $this->PreviousText).' ';
}
if ($this->CurrentPage != $this->PageCount) {
$iTmpPage = $this->CurrentPage + 1;
$sReturn .= ' <a rel="next" href="'.GetUrl($this->Context->Configuration,
$this->Context->SelfUrl,
'',
$this->UrlIdName,
$this->UrlIdValue,
$iTmpPage,
$QSParams).'">'.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $this->NextText).'</a> ';
} else {
$sReturn .= ' '.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $this->NextText).' ';
}
} else {
$sReturn .= ' ';
}
$sReturn .= '</div>';
return $sReturn;
}
// Builds a numeric page list (ie. "prev 1 2 3 next").
function GetNumericList() {
$PreviousText = '<';
$NextText = '>';
if ($this->UseTextOnNumericList) {
$PreviousText .= ' '.$this->PreviousText;
$NextText = ' '.$this->NextText.' '.$NextText;
}
$this->DefineProperties();
// Optimization: place commonly used object properties in local variables
$PageCount = $this->PageCount;
$CurrentPage = $this->CurrentPage;
$PageParameterName = $this->PageParameterName;
$QSParams = $this->QueryStringParams->GetQueryString();
// Variables that help define which page numbers to display:
// Subtract the first and last page from the number of pages to display
$iPagesToDisplay = $this->PagesToDisplay - 2;
if ($iPagesToDisplay <= 8) $iPagesToDisplay = 8;
// Middle navigation point for the pagelist
$MidPoint = ($iPagesToDisplay / 2);
// First page number to display (Based on the current page number and the middle position, figure out which page number to start on)
$FirstPage = $CurrentPage - $MidPoint;
if ($FirstPage < 1) $FirstPage = 1;
// Last page number to display
$LastPage = $FirstPage + ($iPagesToDisplay - 1);
if ($LastPage > $PageCount) {
$LastPage = $PageCount;
$FirstPage = $PageCount - $iPagesToDisplay;
if ($FirstPage < 1) $FirstPage = 1;
}
$sReturn = '
<ol class="'.$this->CssClass.($PageCount > 1?'':' PageListEmpty').'"';
if (!empty($this->PageListID) && $this->PageListID != '') $sReturn .= ' id="'.$this->PageListID.'"';
$sReturn .= '>
';
$Loop = 0;
$iTmpPage = 0;
$Url = GetUrl($this->Context->Configuration,
$this->Context->SelfUrl,
'',
$this->UrlIdName,
$this->UrlIdValue,
'$$1',
$QSParams,
$this->UrlSuffix);
if ($PageCount > 1) {
if ($CurrentPage > 1) {
$iTmpPage = $CurrentPage - 1;
$sReturn .= ' <li><a rel="prev" href="'.str_replace('$$1',
$iTmpPage,
$Url).'">'.Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $PreviousText).'</a></li>
';
} else {
$sReturn .= ' <li>'.Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $PreviousText).'</li>
';
}
// Display first page & elipsis if we have moved past the second page
if ($FirstPage > 2) {
$sReturn .= ' <li><a rel="start" href="'.str_replace('$$1',
1,
$Url).'">1</a></li>
<li>...</li>
';
} elseif ($FirstPage == 2) {
$sReturn .= ' <li><a rel="start" href="'.str_replace('$$1',
1,
$Url).'">1</a></li>
';
}
$Loop = 0;
for ($Loop = 1; $Loop <= $PageCount; $Loop++) {
if (($Loop >= $FirstPage) && ($Loop <= $LastPage)) {
if ($Loop == $CurrentPage) {
$sReturn .= ' <li class="CurrentPage">'.$Loop.'</li>
';
} else {
$sReturn .= ' <li><a'. iif($Loop == 1, ' rel="start"', '') .' href="'.str_replace('$$1',
$Loop,
$Url).'">'.$Loop.'</a></li>
';
}
}
}
// Display last page & elipsis if we are not yet at the second last page
if ($CurrentPage < ($PageCount - $MidPoint) && $PageCount > $this->PagesToDisplay - 1) {
$sReturn .= '<li>...</li>
<li><a href="'.str_replace('$$1',
$PageCount,
$Url).'">'.$PageCount.'</a></li>
';
} else if ($CurrentPage == ($PageCount - $MidPoint) && ($PageCount > $this->PagesToDisplay)) {
$sReturn .= '<li><a href="'.str_replace('$$1',
$PageCount,
$Url).'">'.$PageCount.'</a></li>
';
}
if ($CurrentPage != $PageCount) {
$iTmpPage = $CurrentPage + 1;
$sReturn .= '<li><a rel="next" href="'.str_replace('$$1',
$iTmpPage,
$Url).'">'.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $NextText).'</a></li>
';
} else {
$sReturn .= '<li>'.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $NextText).'</li>
';
}
} else {
$sReturn .= '<li> </li>
';
}
$sReturn .= '</ol>
';
return $sReturn;
}
}
$Context->ObjectFactory->SetReference('PageList', 'RelPageList'); It's tested on PHP 5. If this is sufficient, then we'll see about getting the changes into the core.
Well, it turns out that while rel="" is valid on other types of links, Opera's navigation toolbar ignores it unless they are actually LINK elements... (but at least they don't have to be in the HEAD, yet that is required by the spec.)
Comments
I'm guessing that META name="PageNumber" is a custom thing, because I can't find any evidence of it listed as a standard anywhere.
The correct standardized structure should look like this:
<head> ...other head information... <title>Chapter 5</title > <link rel="start" href="chapter1.html"> <link rel="prev" href="chapter4.html"> <link rel="next" href="chapter6.html"> </head>
For more information on this, see:
Link Structure - W3.org
META Link Relationship Tag
---
In any case, I have two questions:
1) How do you get the "Next" page when one exists??
and
2) How do you get the URL to actually display? The code above literally puts in the words, "[previous url]" directly into the markup. We need the actual URL to display there.
I think the best way to do this would be to extend the Framework.PageList class, since it doesn't do any delegates... otherwise we would have to attach to each control that uses the PageList. But I'm not sure if it's possible to access the Head object to insert those strings while in there.
Going to have to try out a few things...
The page list is not a regular control, its just a class that builds a link list. Unfortunately, since the page list isn't invoked until the relevant control itself is rendered, the head is already rendered by the time this page list class gets executed.
Fortunately, the rel attributes are valid on regular <a links also...you may need to test to see if it works. This is what I came up with:
<?php /* Extension Name: Rel Page List Extension Url: http://lussumo.com/community/discussion/6529/pagination-and-meta-titles/ Description: Inserts appropriate rel attributes into the Vanilla PageList class Version: 1.0 Author: WallPhone Author Url: http://WallPhone.com/ */ if (!defined('IN_VANILLA')) exit(); require_once($Configuration['LIBRARY_PATH'] . '/Framework/Framework.Class.PageList.php'); Class RelPageList Extends PageList { // Builds a literal page list (ie. "previous next") function GetLiteralList() { $this->DefineProperties(); $sReturn = '<div class="'.$this->CssClass.'"'; if ($this->PageListID != '') $sReturn .= ' id="'.$this->PageListID.'"'; $sReturn .= '>'; $QSParams = $this->QueryStringParams->GetQueryString(); // Define the querystring $iTmpPage = 0; if ($this->PageCount > 1) { if ($this->CurrentPage > 1) { $iTmpPage = $this->CurrentPage - 1; $sReturn .= '<a rel="prev" href="'.GetUrl($this->Context->Configuration, $this->Context->SelfUrl, '', $this->UrlIdName, $this->UrlIdValue, $iTmpPage, $QSParams) .'">'.Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $this->PreviousText).'</a> '; } else { $sReturn .= Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $this->PreviousText).' '; } if ($this->CurrentPage != $this->PageCount) { $iTmpPage = $this->CurrentPage + 1; $sReturn .= ' <a rel="next" href="'.GetUrl($this->Context->Configuration, $this->Context->SelfUrl, '', $this->UrlIdName, $this->UrlIdValue, $iTmpPage, $QSParams).'">'.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $this->NextText).'</a> '; } else { $sReturn .= ' '.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $this->NextText).' '; } } else { $sReturn .= ' '; } $sReturn .= '</div>'; return $sReturn; } // Builds a numeric page list (ie. "prev 1 2 3 next"). function GetNumericList() { $PreviousText = '<'; $NextText = '>'; if ($this->UseTextOnNumericList) { $PreviousText .= ' '.$this->PreviousText; $NextText = ' '.$this->NextText.' '.$NextText; } $this->DefineProperties(); // Optimization: place commonly used object properties in local variables $PageCount = $this->PageCount; $CurrentPage = $this->CurrentPage; $PageParameterName = $this->PageParameterName; $QSParams = $this->QueryStringParams->GetQueryString(); // Variables that help define which page numbers to display: // Subtract the first and last page from the number of pages to display $iPagesToDisplay = $this->PagesToDisplay - 2; if ($iPagesToDisplay <= 8) $iPagesToDisplay = 8; // Middle navigation point for the pagelist $MidPoint = ($iPagesToDisplay / 2); // First page number to display (Based on the current page number and the middle position, figure out which page number to start on) $FirstPage = $CurrentPage - $MidPoint; if ($FirstPage < 1) $FirstPage = 1; // Last page number to display $LastPage = $FirstPage + ($iPagesToDisplay - 1); if ($LastPage > $PageCount) { $LastPage = $PageCount; $FirstPage = $PageCount - $iPagesToDisplay; if ($FirstPage < 1) $FirstPage = 1; } $sReturn = ' <ol class="'.$this->CssClass.($PageCount > 1?'':' PageListEmpty').'"'; if (!empty($this->PageListID) && $this->PageListID != '') $sReturn .= ' id="'.$this->PageListID.'"'; $sReturn .= '> '; $Loop = 0; $iTmpPage = 0; $Url = GetUrl($this->Context->Configuration, $this->Context->SelfUrl, '', $this->UrlIdName, $this->UrlIdValue, '$$1', $QSParams, $this->UrlSuffix); if ($PageCount > 1) { if ($CurrentPage > 1) { $iTmpPage = $CurrentPage - 1; $sReturn .= ' <li><a rel="prev" href="'.str_replace('$$1', $iTmpPage, $Url).'">'.Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $PreviousText).'</a></li> '; } else { $sReturn .= ' <li>'.Iif($this->PreviousImage != '', '<img src="'.$this->PreviousImage.'" alt="'.$this->PreviousText.'" />', $PreviousText).'</li> '; } // Display first page & elipsis if we have moved past the second page if ($FirstPage > 2) { $sReturn .= ' <li><a rel="start" href="'.str_replace('$$1', 1, $Url).'">1</a></li> <li>...</li> '; } elseif ($FirstPage == 2) { $sReturn .= ' <li><a rel="start" href="'.str_replace('$$1', 1, $Url).'">1</a></li> '; } $Loop = 0; for ($Loop = 1; $Loop <= $PageCount; $Loop++) { if (($Loop >= $FirstPage) && ($Loop <= $LastPage)) { if ($Loop == $CurrentPage) { $sReturn .= ' <li class="CurrentPage">'.$Loop.'</li> '; } else { $sReturn .= ' <li><a'. iif($Loop == 1, ' rel="start"', '') .' href="'.str_replace('$$1', $Loop, $Url).'">'.$Loop.'</a></li> '; } } } // Display last page & elipsis if we are not yet at the second last page if ($CurrentPage < ($PageCount - $MidPoint) && $PageCount > $this->PagesToDisplay - 1) { $sReturn .= '<li>...</li> <li><a href="'.str_replace('$$1', $PageCount, $Url).'">'.$PageCount.'</a></li> '; } else if ($CurrentPage == ($PageCount - $MidPoint) && ($PageCount > $this->PagesToDisplay)) { $sReturn .= '<li><a href="'.str_replace('$$1', $PageCount, $Url).'">'.$PageCount.'</a></li> '; } if ($CurrentPage != $PageCount) { $iTmpPage = $CurrentPage + 1; $sReturn .= '<li><a rel="next" href="'.str_replace('$$1', $iTmpPage, $Url).'">'.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $NextText).'</a></li> '; } else { $sReturn .= '<li>'.Iif($this->NextImage != '', '<img src="'.$this->NextImage.'" alt="'.$this->NextText.'" />', $NextText).'</li> '; } } else { $sReturn .= '<li> </li> '; } $sReturn .= '</ol> '; return $sReturn; } } $Context->ObjectFactory->SetReference('PageList', 'RelPageList');
It's tested on PHP 5. If this is sufficient, then we'll see about getting the changes into the core.