Permalink
Browse files

API: Remove public access to frequency and priorities.

Cleaned up related functions and general spring clean of the module. Documented example of manually setting routes through an extension class.
  • Loading branch information...
1 parent 5bc3e07 commit 929e97accfd189283082877aa2e6abeeea2eaf06 @wilr committed Jul 6, 2012
Showing with 176 additions and 142 deletions.
  1. +3 −3 README.md
  2. +70 −79 code/GoogleSitemap.php
  3. +36 −25 code/GoogleSitemapDecorator.php
  4. +60 −28 docs/en/index.md
  5. +1 −1 templates/GoogleSitemap.ss
  6. +6 −6 tests/GoogleSitemapTest.php
View
@@ -2,11 +2,11 @@
## Maintainer Contact
- * Will Rossiter (Nickname: wrossiter, willr) <will@fullscreen.io>
+* Will Rossiter (Nickname: wrossiter, willr) <will@fullscreen.io>
## Requirements
- * SilverStripe 3.0
+* SilverStripe 3.0
## Documentation
@@ -18,7 +18,7 @@ information on your site to be discovered by Google quickly.
Therefore, all Silverstripe websites contain a special controller which can
be visited: http://yoursite.com/sitemap.xml
-See http://en.wikipedia.org/wiki/Sitemaps for info on this format
+See http://en.wikipedia.org/wiki/Sitemaps for info on this format.
## Usage Overview
View
@@ -1,6 +1,12 @@
<?php
/**
- * Initial implementation of Sitemap support.
+ * Sitemaps are a way to tell Google about pages on your site that they might
+ * not otherwise discover. In its simplest terms, a XML Sitemap—usually called
+ * Sitemap, with a capital S—is a list of the pages on your website. Creating
+ * and submitting a Sitemap helps make sure that Google knows about all the
+ * pages on your site, including URLs that may not be discoverable by Google's
+ * normal crawling process.
+ *
* GoogleSitemap should handle requests to 'sitemap.xml'
* the other two classes are used to render the sitemap.
*
@@ -44,25 +50,12 @@ class GoogleSitemap extends Controller {
protected static $use_show_in_search = true;
/**
- * List of DataObjects to show in sitemap.xml
+ * List of DataObject class names to include. As well as the change
+ * frequency and priority of each class.
*
* @var array
*/
- public static $google_sitemap_dataobjects = array();
-
- /**
- * List of DataObjects change frequency
- *
- * @var array
- */
- public static $google_sitemap_dataobjects_changefreq = array();
-
- /**
- * List of DataObjects priority
- *
- * @var array
- */
- public static $google_sitemap_dataobjects_priority = array();
+ private static $dataobjects = array();
/**
* Decorates the given DataObject with {@link GoogleSitemapDecorator}
@@ -82,15 +75,10 @@ public static function register_dataobject($className, $changeFreq = 'monthly',
if (!self::is_registered($className)) {
Object::add_extension($className, 'GoogleSitemapDecorator');
- self::$google_sitemap_dataobjects[] = $className;
-
- if (!$changeFreq) {
- self::$google_sitemap_dataobjects_changefreq[] = "monthly";
- } else {
- self::$google_sitemap_dataobjects_changefreq[] = $changeFreq;
- }
-
- self::$google_sitemap_dataobjects_priority[] = $priority;
+ self::$dataobjects[$className] = array(
+ 'frequency' => ($changeFreq) ? $changeFreq : 'monthly',
+ 'priority' => ($priority) ? $priority : '0.6'
+ );
}
}
@@ -102,31 +90,31 @@ public static function register_dataobject($className, $changeFreq = 'monthly',
* @return bool
*/
public static function is_registered($className) {
- return in_array($className, self::$google_sitemap_dataobjects);
+ return isset(self::$dataobjects[$className]);
}
/**
- * Adds DataObjects to the existing DataObjectSet with pages from the
- * site tree
+ * Returns a list containing each viewable {@link DataObject} instance of
+ * the registered class names.
*
* @return ArrayList
*/
- protected function addRegisteredDataObjects() {
+ protected function getDataObjects() {
$output = new ArrayList();
- foreach(self::$google_sitemap_dataobjects as $index => $className) {
- $dataObjectSet = DataObject::get($className);
+ foreach(self::$dataobjects as $class => $config) {
+ $instances = new DataList($class);
- if($dataObjectSet) {
- foreach($dataObjectSet as $dataObject) {
- if($dataObject->canView()) {
- $dataObject->ChangeFreq = self::$google_sitemap_dataobjects_changefreq[$index];
+ if($instances) {
+ foreach($instances as $obj) {
+ if($obj->canView()) {
+ $obj->ChangeFreq = $config['frequency'];
- if(!isset($dataObject->Priority)) {
- $dataObject->Priority = self::$google_sitemap_dataobjects_priority[$index];
+ if(!isset($obj->Priority)) {
+ $obj->Priority = $config['priority'];
}
- $output->push($dataObject);
+ $output->push($obj);
}
}
}
@@ -136,76 +124,77 @@ protected function addRegisteredDataObjects() {
}
/**
- * Returns all the links to {@link SiteTree} pages and
- * {@link DataObject} urls on the page.
+ * Returns a list containing each viewable {@link SiteTree} instance. If
+ * you wish to exclude a particular class from the sitemap, simply set
+ * the priority of the class to -1.
*
- * @return DataObjectSet
+ * @return ArrayList
*/
- public function Items() {
- $filter = '';
+ protected function getPages() {
+ if(!class_exists('SiteTree')) return new ArrayList();
- $bt = defined('DB::USE_ANSI_SQL') ? "\"" : "`";
-
- if(self::$use_show_in_search) {
- $filter = "{$bt}ShowInSearch{$bt} = 1";
- }
-
- $pages = class_exists('SiteTree') ? Versioned::get_by_stage('SiteTree', 'Live', $filter) : false;
-
- $newPages = new ArrayList();
+ $filter = (self::$use_show_in_search) ? "\"ShowInSearch\" = 1" : "";
+ $pages = Versioned::get_by_stage('SiteTree', 'Live', $filter);
+ $output = new ArrayList();
if($pages) {
foreach($pages as $page) {
- // Only include pages from this host and pages which are not an
- // instance of ErrorPage. We prefix $_SERVER['HTTP_HOST'] with
- // 'http://' so that parse_url to help parse_url identify the
- // host name component; we could use another protocol (like ftp
- // as the prefix and the code would work the same.
$pageHttp = parse_url($page->AbsoluteLink(), PHP_URL_HOST);
$hostHttp = parse_url('http://' . $_SERVER['HTTP_HOST'], PHP_URL_HOST);
if(($pageHttp == $hostHttp) && !($page instanceof ErrorPage)) {
-
- // If the page has been set to 0 priority, we set a flag so
- // it won't be included
if($page->canView() && (!isset($page->Priority) || $page->Priority > 0)) {
- $page->setChangeFrequency();
- $newPages->push($page);
+ $
@frankmullenger

frankmullenger Jul 8, 2012

Think this might be a type, evaluates to $ArrayList and triggers an undefined variable warning for me.

@wilr

wilr Jul 9, 2012

Owner

Good catch, my tests didn't get into that since I was only using the framework. Try now

+ $output->push($page);
}
}
}
-
}
- $newPages->merge($this->addRegisteredDataObjects());
+ return $output;
+ }
- $this->extend('updateItems', $newPages);
+ /**
+ * Constructs the list of data to include in the rendered sitemap. Links
+ * can include pages from the website, dataobjects (such as forum posts)
+ * as well as custom registered paths.
+ *
+ * @return ArrayList
+ */
+ public function Items() {
+ $output = new ArrayList();
+ $output->merge($this->getPages());
+ $output->merge($this->getDataObjects());
+
+ $this->extend('updateItems', $output);
- return $newPages;
+ return $output;
}
/**
- * Notifies Google about changes to your sitemap.
- *
- * Triggered automatically on every publish/unpublish of a page.
- * This behaviour is disabled by default, enable with:
+ * Notifies Google about changes to your sitemap. This behavior is disabled
+ * by default, enable with:
*
* <code>
* GoogleSitemap::enable_google_notificaton();
* </code>
*
- * If the site is in "dev-mode", no ping will be sent regardless wether
+ * After notifications have been enabled, every publish / unpublish of a page.
+ * will notify Google of the update.
+ *
+ * If the site is in development mode no ping will be sent regardless whether
* the Google notification is enabled.
*
* @return string Response text
*/
- static function ping() {
+ public static function ping() {
if(!self::$enabled) return false;
- //Don't ping if the site has disabled it, or if the site is in dev mode
- if(!GoogleSitemap::$google_notification_enabled || Director::isDev())
+ // Don't ping if the site has disabled it, or if the site is in dev mode
+ if(!GoogleSitemap::$google_notification_enabled || Director::isDev()) {
return;
-
+ }
+
$location = urlencode(Controller::join_links(
Director::absoluteBaseURL(),
'sitemap.xml'
@@ -241,7 +230,7 @@ public static function disable_google_notification() {
/**
* Default controller handler for the sitemap.xml file
*/
- function index($url) {
+ public function index($url) {
if(self::$enabled) {
SSViewer::set_source_file_comments(false);
@@ -255,7 +244,8 @@ function index($url) {
}
/**
- * Enable the sitemap.xml file
+ * Enable Google Sitemap support. Requests to the sitemap.xml route will
+ * result in an XML sitemap being provided.
*
* @return void
*/
@@ -264,7 +254,8 @@ public static function enable() {
}
/**
- * Disable the sitemap.xml file
+ * Disable Google Sitemap support. Any requests to the sitemap.xml route
+ * will produce a 404 response.
*
* @return void
*/
@@ -15,15 +15,17 @@ class GoogleSitemapDecorator extends DataExtension {
*/
class GoogleSitemapSiteTreeDecorator extends DataExtension {
- function extraStatics($class = null, $extension = null) {
- return array(
- 'db' => array(
- "Priority" => "Varchar(5)",
- ),
- );
- }
+ /**
+ * @var array
+ */
+ public static $db = array(
+ "Priority" => "Varchar(5)"
+ );
- function updateSettingsFields(&$fields) {
+ /**
+ * @param FieldList
+ */
+ public function updateSettingsFields(&$fields) {
$prorities = array(
'' => _t('SiteTree.PRIORITYAUTOSET', 'Auto-set based on page depth'),
'-1' => _t('SiteTree.PRIORITYNOTINDEXED', "Not indexed"), // We set this to -ve one because a blank value implies auto-generation of Priority
@@ -53,17 +55,23 @@ function updateSettingsFields(&$fields) {
));
}
- function updateFieldLabels(&$labels) {
+ public function updateFieldLabels(&$labels) {
parent::updateFieldLabels($labels);
$labels['Priority'] = _t('SiteTree.METAPAGEPRIO', "Page Priority");
}
- function onAfterPublish() {
+ /**
+ * @return void
+ */
+ public function onAfterPublish() {
GoogleSitemap::ping();
}
- function onAfterUnpublish() {
+ /**
+ * @return void
+ */
+ public function onAfterUnpublish() {
GoogleSitemap::ping();
}
@@ -73,7 +81,7 @@ function onAfterUnpublish() {
*
* @return float
*/
- function getPriority() {
+ public function getPriority() {
if(!$this->owner->getField('Priority')) {
$parentStack = $this->owner->parentStack();
$numParents = is_array($parentStack) ? count($parentStack) - 1 : 0;
@@ -91,42 +99,45 @@ function getPriority() {
}
/**
- * Set a pages change frequency calculated by pages age and number of versions.
- * Google expects always, hourly, daily, weekly, monthly, yearly or never as values.
+ * Returns a pages change frequency calculated by pages age and number of
+ * versions. Google expects always, hourly, daily, weekly, monthly, yearly
+ * or never as values.
*
+ * @see http://support.google.com/webmasters/bin/answer.py?hl=en&answer=183668&topic=8476&ctx=topic
+ *
* @return void
*/
- public function setChangeFrequency() {
- // The one field that isn't easy to deal with in the template is
- // Change frequency, so we set that here.
+ public function getChangeFrequency() {
$date = date('Y-m-d H:i:s');
-
$prop = $this->owner->toMap();
+
$created = new SS_Datetime();
$created->value = (isset($prop['Created'])) ? $prop['Created'] : $date;
$now = new SS_Datetime();
$now->value = $date;
+
$versions = (isset($prop['Version'])) ? $prop['Version'] : 1;
-
$timediff = $now->format('U') - $created->format('U');
// Check how many revisions have been made over the lifetime of the
// Page for a rough estimate of it's changing frequency.
$period = $timediff / ($versions + 1);
if ($period > 60 * 60 * 24 * 365) {
- $this->owner->ChangeFreq = 'yearly';
+ $freq = 'yearly';
} elseif ($period > 60 * 60 * 24 * 30) {
- $this->owner->ChangeFreq = 'monthly';
+ $freq = 'monthly';
} elseif ($period > 60 * 60 * 24 * 7) {
- $this->owner->ChangeFreq = 'weekly';
+ $freq = 'weekly';
} elseif ($period > 60 * 60 * 24) {
- $this->owner->ChangeFreq = 'daily';
+ $freq = 'daily';
} elseif ($period > 60 * 60) {
- $this->owner->ChangeFreq = 'hourly';
+ $freq = 'hourly';
} else {
- $this->owner->ChangeFreq = 'always';
+ $freq = 'always';
}
+
+ return $freq;
}
}
Oops, something went wrong.

0 comments on commit 929e97a

Please sign in to comment.