Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

API register_routes() for registering custom paths.

This replaces the existing updateItems() + extension hook in favour of consistency with the register_dataobject() interface.

Note that this will likely be superseded by something to do with the Config API in the future.
  • Loading branch information...
commit 1c5e737d06523136f98b9f34b882043ba792d6d1 1 parent 747059b
Will Rossiter wilr authored
103 code/GoogleSitemap.php
View
@@ -29,7 +29,7 @@
class GoogleSitemap {
/**
- * List of DataObject class names to include. As well as the change
+ * List of {@link DataObject} class names to include. As well as the change
* frequency and priority of each class.
*
* @var array
@@ -37,6 +37,14 @@ class GoogleSitemap {
private static $dataobjects = array();
/**
+ * List of custom routes to include in the sitemap (such as controller
+ * subclasses) as well as the change frequency and priority.
+ *
+ * @var array
+ */
+ private static $routes = array();
+
+ /**
* Decorates the given DataObject with {@link GoogleSitemapDecorator}
* and pushes the class name to the registered DataObjects.
* Note that all registered DataObjects need the method AbsoluteLink().
@@ -62,6 +70,25 @@ public static function register_dataobject($className, $changeFreq = 'monthly',
}
/**
+ * Registers multiple dataobjects in a single line. See {@link register_dataobject}
+ * for the heavy lifting
+ *
+ * @param array $dataobjects array of class names of DataObject to register
+ * @param string $changeFreq how often is this DataObject updated?
+ * Possible values:
+ * always, hourly, daily, weekly, monthly, yearly, never
+ * @param string $priority How important is this DataObject in comparison to other urls?
+ * Possible values: 0.1, 0.2 ... , 0.9, 1.0
+ *
+ * @return void
+ */
+ public static function register_dataobjects($dataobjects, $changeFreq = 'monthly', $priority = '0.6') {
+ foreach($dataobjects as $obj) {
+ self::register_dataobject($obj, $changeFreq, $priority);
+ }
+ }
+
+ /**
* Checks whether the given class name is already registered or not.
*
* @param string $className Name of DataObject to check
@@ -83,12 +110,57 @@ public static function unregister_dataobject($className) {
/**
* Clears registered {@link DataObjects}. Useful for unit tests.
+ *
+ * @return void
*/
public static function clear_registered_dataobjects() {
self::$dataobjects = array();
}
/**
+ * Register a given route to the sitemap list
+ *
+ * @param string
+ * @param string
+ * @param string
+ *
+ * @return void
+ */
+ public static function register_route($route, $changeFreq = 'monthly', $priority = '0.6') {
+ self::$routes = array_merge(self::$routes, array(
+ $route => array(
+ 'frequency' => ($changeFreq) ? $changeFreq : 'monthly',
+ 'priority' => ($priority) ? $priority : '0.6'
+ )
+ ));
+ }
+
+ /**
+ * Registers a given list of relative urls. Will be merged with the current
+ * registered routes. If you want to replace them, please call {@link clear_routes}
+ *
+ * @param array
+ * @param string
+ * @param string
+ *
+ * @return void
+ */
+ public static function register_routes($routes, $changeFreq = 'monthly', $priority = '0.6') {
+ foreach($routes as $route) {
+ self::register_route($route, $changeFreq, $priority);
+ }
+ }
+
+ /**
+ * Clears registered routes
+ *
+ * @return void
+ */
+ public static function clear_registered_routes() {
+ self::$routes = array();
+ }
+
+ /**
* 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.
@@ -107,6 +179,22 @@ public static function get_items($class, $page = 1) {
$filter = ($filter) ? "\"ShowInSearch\" = 1" : "";
$instances = Versioned::get_by_stage('SiteTree', 'Live', $filter);
}
+ else if($class == "GoogleSitemapRoute") {
+ $instances = array_slice(self::$routes, ($page - 1) * $count, $count);
+ $output = new ArrayList();
+
+ if($instances) {
+ foreach($instances as $route => $config) {
+ $output->push(new ArrayData(array(
+ 'AbsoluteLink' => Director::absoluteURL($route),
+ 'ChangeFrequency' => $config['frequency'],
+ 'GooglePriority' => $config['priority']
+ )));
+ }
+ }
+
+ return $output;
+ }
else {
$instances = new DataList($class);
}
@@ -196,7 +284,7 @@ public static function get_sitemaps() {
}
}
- if(self::$dataobjects) {
+ if(count(self::$dataobjects) > 0) {
foreach(self::$dataobjects as $class => $config) {
$list = new DataList($class);
$list = $list->sort('LastEdited ASC');
@@ -220,6 +308,17 @@ public static function get_sitemaps() {
}
}
+ if(count(self::$routes) > 0) {
+ $needed = ceil(count(self::$routes) / $countPerFile);
+
+ for($i = 1; $i <= $needed; $i++) {
+ $sitemaps->push(new ArrayData(array(
+ 'ClassName' => 'GoogleSitemapRoute',
+ 'Page' => $i
+ )));
+ }
+ }
+
return $sitemaps;
}
15 docs/en/index.md
View
@@ -103,4 +103,17 @@ instead of the previous code you would write:
See the following blog post for more information:
-http://www.silvercart.org/blog/dataobjects-and-googlesitemaps/
+http://www.silvercart.org/blog/dataobjects-and-googlesitemaps/
+
+### Including custom routes
+
+Occasionally you may have a need to include custom url's in your sitemap for
+your Controllers and other pages which don't exist in the database. To update
+the sitemap to include those links call register_routes() with your array of
+urls to include.
+
+ GoogleSitemap::register_routes(array(
+ '/my-custom-controller/',
+ '/Security/',
+ '/Security/login/'
+ ));
38 tests/GoogleSitemapTest.php
View
@@ -22,12 +22,24 @@ public function setUp() {
}
GoogleSitemap::clear_registered_dataobjects();
+ GoogleSitemap::clear_registered_routes();
}
public function tearDown() {
parent::tearDown();
GoogleSitemap::clear_registered_dataobjects();
+ GoogleSitemap::clear_registered_routes();
+ }
+
+ public function testIndexFileWithCustomRoute() {
+ GoogleSitemap::register_route('/test/');
+
+ $response = $this->get('sitemap.xml');
+ $body = $response->getBody();
+
+ $expected = "<loc>". Director::absoluteURL("sitemap.xml/sitemap/GoogleSitemapRoute/1") ."</loc>";
+ $this->assertEquals(1, substr_count($body, $expected) , 'A link to the custom routes exists');
}
@@ -49,6 +61,17 @@ public function testGetItems() {
$this->assertEquals(0, GoogleSitemap::get_items('GoogleSitemapTest_UnviewableDataObject', 1)->count());
}
+ public function testGetItemsWithCustomRoutes() {
+ GoogleSitemap::register_routes(array(
+ '/test-route/',
+ '/someother-route/',
+ '/fake-sitemap-route/'
+ ));
+
+ $items = GoogleSitemap::get_items('GoogleSitemapRoute', 1);
+ $this->assertEquals(3, $items->count());
+ }
+
public function testAccessingSitemapRootXMLFile() {
GoogleSitemap::register_dataobject("GoogleSitemapTest_DataObject");
GoogleSitemap::register_dataobject("GoogleSitemapTest_OtherDataObject");
@@ -98,6 +121,21 @@ public function testIndexFilePaginatedSitemapFiles() {
Config::inst()->update('GoogleSitemap', 'objects_per_sitemap', $original);
}
+ public function testRegisterRoutesIncludesAllRoutes() {
+ GoogleSitemap::register_route('/test/');
+ GoogleSitemap::register_routes(array(
+ '/test/', // duplication should be replaced
+ '/unittests/',
+ '/anotherlink/'
+ ), 'weekly');
+
+ $response = $this->get('sitemap.xml/sitemap/GoogleSitemapRoute/1');
+ $body = $response->getBody();
+
+ $this->assertEquals(200, $response->getStatusCode(), 'successful loaded nested sitemap');
+ $this->assertEquals(3, substr_count($body, "<loc>"));
+ }
+
public function testAccessingNestedSiteMap() {
$original = Config::inst()->get('GoogleSitemap', 'objects_per_sitemap');
Config::inst()->update('GoogleSitemap', 'objects_per_sitemap', 1);
Please sign in to comment.
Something went wrong with that request. Please try again.