API Use canonical URL for all repositories, and instead redirect from non-versioned page to correct canonical URL for each page.

This commit is contained in:
Damian Mooyman 2015-04-24 18:17:25 +12:00
parent 7b1a37f430
commit a7094a68af
8 changed files with 122 additions and 50 deletions

View File

@ -6,12 +6,12 @@ php:
env:
- DB=MYSQL CORE_RELEASE=3.1
- DB=MYSQL CORE_RELEASE=master
- DB=MYSQL CORE_RELEASE=3
matrix:
include:
- php: 5.4
env: DB=MYSQL CORE_RELEASE=master
env: DB=MYSQL CORE_RELEASE=3
before_script:
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
@ -19,4 +19,4 @@ before_script:
- cd ~/builds/ss
script:
- phpunit docsviewer/tests/
- phpunit docsviewer/tests/

View File

@ -54,6 +54,8 @@ class DocumentationManifest {
*/
protected $pages = array();
protected $redirects = array();
/**
* @var DocumentationEntity
*/
@ -224,7 +226,8 @@ class DocumentationManifest {
*/
protected function init() {
if (!$this->forceRegen && $data = $this->cache->load($this->cacheKey)) {
$this->pages = $data;
$this->pages = $data['pages'];
$this->redirects = $data['redirects'];
$this->inited = true;
} else {
$this->regenerate();
@ -245,6 +248,14 @@ class DocumentationManifest {
return $this->pages;
}
public function getRedirects() {
if(!$this->inited) {
$this->init();
}
return $this->redirects;
}
/**
* Returns a particular page for the requested URL.
*
@ -275,6 +286,21 @@ class DocumentationManifest {
}
}
/**
* Get any redirect for the given url
*
* @param type $url
* @return string
*/
public function getRedirect($url) {
$pages = $this->getRedirects();
$url = $this->normalizeUrl($url);
if(isset($pages[$url])) {
return $pages[$url];
}
}
/**
* Regenerates the manifest by scanning the base path.
*
@ -287,6 +313,7 @@ class DocumentationManifest {
'file_callback' => array($this, 'handleFile')
));
$this->redirects = array();
foreach($this->getEntities() as $entity) {
$this->entity = $entity;
@ -328,12 +355,63 @@ class DocumentationManifest {
}
if ($cache) {
$this->cache->save($this->pages, $this->cacheKey);
$this->cache->save(
array(
'pages' => $this->pages,
'redirects' => $this->redirects
),
$this->cacheKey
);
}
$this->inited = true;
}
/**
* Remove the link_base from the start of a link
*
* @param string $link
* @return string
*/
protected function stripLinkBase($link) {
return ltrim(str_replace(
Config::inst()->get('DocumentationViewer', 'link_base'),
'',
$link
), '/');
}
/**
*
* @param DocumentationPage $page
* @param string $basename
* @param string $path
*/
protected function addPage($page, $basename, $path) {
$link = $this->stripLinkBase($page->Link());
$this->pages[$link] = array(
'title' => $page->getTitle(),
'basename' => $basename,
'filepath' => $path,
'type' => get_class($page),
'entitypath' => $this->entity->getPath(),
'summary' => $page->getSummary()
);
}
/**
* Add a redirect
*
* @param string $from
* @param string $to
*/
protected function addRedirect($from, $to) {
$fromLink = $this->stripLinkBase($from);
$toLink = $this->stripLinkBase($to);
$this->redirects[$fromLink] = $toLink;
}
/**
*
*/
@ -342,20 +420,15 @@ class DocumentationManifest {
'DocumentationFolder', $this->entity, $basename, $path
);
$link = ltrim(str_replace(
Config::inst()->get('DocumentationViewer', 'link_base'),
'',
$folder->Link()
), '/');
// Add main folder link
$fullLink = $folder->Link();
$this->addPage($folder, $basename, $path);
$this->pages[$link] = array(
'title' => $folder->getTitle(),
'basename' => $basename,
'filepath' => $path,
'type' => 'DocumentationFolder',
'entitypath' => $this->entity->getPath(),
'summary' => ''
);
// Add alternative link
$shortLink = $folder->Link(true);
if($shortLink != $fullLink) {
$this->addRedirect($shortLink, $fullLink);
}
}
/**
@ -379,20 +452,15 @@ class DocumentationManifest {
// populate any meta data
$page->getMarkdown();
$link = ltrim(str_replace(
Config::inst()->get('DocumentationViewer', 'link_base'),
'',
$page->Link()
), '/');
// Add main link
$fullLink = $page->Link();
$this->addPage($page, $basename, $path);
$this->pages[$link] = array(
'title' => $page->getTitle(),
'filepath' => $path,
'entitypath' => $this->entity->getPath(),
'basename' => $basename,
'type' => 'DocumentationPage',
'summary' => $page->getSummary()
);
// If this is a stable version, add the short link
$shortLink = $page->Link(true);
if($fullLink != $shortLink) {
$this->addRedirect($shortLink, $fullLink);
}
}
/**

View File

@ -247,6 +247,10 @@ class DocumentationViewer extends Controller {
));
return new SS_HTTPResponse($body, 200);
} else if($redirect = $this->getManifest()->getRedirect($url)) {
$response = new SS_HTTPResponse();
$to = Controller::join_links(Director::baseURL(), $base, $redirect);
return $response->redirect($to, 301);
} else if(!$url || $url == $lang) {
$body = $this->renderWith(array(
"DocumentationViewer_DocumentationFolder",

View File

@ -112,9 +112,11 @@ class DocumentationEntity extends ViewableData {
*
* Includes the version information
*
* @param boolean $short If true, will attempt to return a short version of the url
* This might omit the version number if this is the default version.
* @return string
*/
public function Link() {
public function Link($short = false) {
if($this->getIsDefaultEntity()) {
$base = Controller::join_links(
Config::inst()->get('DocumentationViewer', 'link_base'),
@ -132,7 +134,7 @@ class DocumentationEntity extends ViewableData {
$base = ltrim(str_replace('//', '/', $base), '/');
if($this->stable) {
if($short && $this->stable) {
return $base;
}

View File

@ -229,14 +229,13 @@ class DocumentationPage extends ViewableData {
* Returns the URL that will be required for the user to hit to view the
* given document base name.
*
* @param string $file
* @param string $path
*
* @param boolean $short If true, will attempt to return a short version of the url
* This might omit the version number if this is the default version.
* @return string
*/
public function Link() {
public function Link($short = false) {
return ltrim(Controller::join_links(
$this->entity->Link(),
$this->entity->Link($short),
$this->getRelativeLink()
), '/');
}

View File

@ -15,7 +15,8 @@
}],
"require": {
"silverstripe/framework": "~3.1",
"erusev/parsedown-extra": "0.2.2"
"erusev/parsedown-extra": "0.2.2",
"erusev/parsedown": "~1.1.0"
},
"suggest": {
"silverstripe/staticpublisher": "Allows publishing documentation as HTML"

View File

@ -84,8 +84,8 @@ class DocumentationManifestTests extends SapphireTest {
'en/testdocs/2.3/subfolder/subsubfolder/',
'en/testdocs/2.3/subfolder/subsubfolder/subsubpage/',
'en/testdocs/2.3/test/',
'en/testdocs/',
'en/testdocs/test/',
'en/testdocs/2.4/',
'en/testdocs/2.4/test/',
'en/testdocs/3.0/',
'en/testdocs/3.0/changelog/',
'en/testdocs/3.0/tutorials/',

View File

@ -98,13 +98,13 @@ class DocumentationViewerTest extends FunctionalTest {
// 2.4 is the stable release. Not in the URL
$response = $this->get('dev/docs/en/doc_test/');
$response = $this->get('dev/docs/en/doc_test/2.4');
$this->assertEquals($response->getStatusCode(), 200, 'Existing base folder');
$this->assertContains('english test', $response->getBody(), 'Toplevel content page');
// accessing 2.4 is redirects to the version without the version number.
$response = $this->get('dev/docs/en/doc_test/2.4/');
$this->assertEquals($response->getStatusCode(), 404, 'Existing base folder redirects to without version');
// accessing base redirects to the version with the version number.
$response = $this->get('dev/docs/en/doc_test/');
$this->assertEquals($response->getStatusCode(), 301, 'Existing base folder redirects to with version');
$response = $this->get('dev/docs/en/doc_test/3.0/');
$this->assertEquals($response->getStatusCode(), 200, 'Existing base folder');
@ -156,7 +156,7 @@ class DocumentationViewerTest extends FunctionalTest {
$this->assertEquals($expected, $actual);
$response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/doc_test/'), DataModel::inst());
$response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/doc_test/2.4/'), DataModel::inst());
$this->assertEquals('current', $v->getMenu()->first()->LinkingMode);
// 2.4 stable release has 1 child page (not including index)
@ -164,14 +164,12 @@ class DocumentationViewerTest extends FunctionalTest {
// menu should contain all the english entities
$expected = array(
'dev/docs/en/doc_test/' => 'Doc Test',
'dev/docs/en/doc_test/2.4/' => 'Doc Test',
'dev/docs/en/documentationvieweraltmodule1/' => 'DocumentationViewerAltModule1',
'dev/docs/en/documentationvieweraltmodule2/' => 'DocumentationViewerAltModule2'
);
$this->assertEquals($expected, $v->getMenu()->map('Link', 'Title'));
$this->assertEquals($expected, $v->getMenu()->map('Link', 'Title'));
}