Merge pull request #64 from tractorcow/pulls/canonical-url

API Use canonical URL for all repositories
This commit is contained in:
Cam Findlay 2015-05-01 11:18:36 +12:00
commit 3a239fcdfa
8 changed files with 122 additions and 50 deletions

View File

@ -6,12 +6,12 @@ php:
env: env:
- DB=MYSQL CORE_RELEASE=3.1 - DB=MYSQL CORE_RELEASE=3.1
- DB=MYSQL CORE_RELEASE=master - DB=MYSQL CORE_RELEASE=3
matrix: matrix:
include: include:
- php: 5.4 - php: 5.4
env: DB=MYSQL CORE_RELEASE=master env: DB=MYSQL CORE_RELEASE=3
before_script: before_script:
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support - git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support

View File

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

View File

@ -247,6 +247,10 @@ class DocumentationViewer extends Controller {
)); ));
return new SS_HTTPResponse($body, 200); 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) { } else if(!$url || $url == $lang) {
$body = $this->renderWith(array( $body = $this->renderWith(array(
"DocumentationViewer_DocumentationFolder", "DocumentationViewer_DocumentationFolder",

View File

@ -112,9 +112,11 @@ class DocumentationEntity extends ViewableData {
* *
* Includes the version information * 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 * @return string
*/ */
public function Link() { public function Link($short = false) {
if($this->getIsDefaultEntity()) { if($this->getIsDefaultEntity()) {
$base = Controller::join_links( $base = Controller::join_links(
Config::inst()->get('DocumentationViewer', 'link_base'), Config::inst()->get('DocumentationViewer', 'link_base'),
@ -132,7 +134,7 @@ class DocumentationEntity extends ViewableData {
$base = ltrim(str_replace('//', '/', $base), '/'); $base = ltrim(str_replace('//', '/', $base), '/');
if($this->stable) { if($short && $this->stable) {
return $base; 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 * Returns the URL that will be required for the user to hit to view the
* given document base name. * given document base name.
* *
* @param string $file * @param boolean $short If true, will attempt to return a short version of the url
* @param string $path * This might omit the version number if this is the default version.
*
* @return string * @return string
*/ */
public function Link() { public function Link($short = false) {
return ltrim(Controller::join_links( return ltrim(Controller::join_links(
$this->entity->Link(), $this->entity->Link($short),
$this->getRelativeLink() $this->getRelativeLink()
), '/'); ), '/');
} }

View File

@ -15,7 +15,8 @@
}], }],
"require": { "require": {
"silverstripe/framework": "~3.1", "silverstripe/framework": "~3.1",
"erusev/parsedown-extra": "0.2.2" "erusev/parsedown-extra": "0.2.2",
"erusev/parsedown": "~1.1.0"
}, },
"suggest": { "suggest": {
"silverstripe/staticpublisher": "Allows publishing documentation as HTML" "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/',
'en/testdocs/2.3/subfolder/subsubfolder/subsubpage/', 'en/testdocs/2.3/subfolder/subsubfolder/subsubpage/',
'en/testdocs/2.3/test/', 'en/testdocs/2.3/test/',
'en/testdocs/', 'en/testdocs/2.4/',
'en/testdocs/test/', 'en/testdocs/2.4/test/',
'en/testdocs/3.0/', 'en/testdocs/3.0/',
'en/testdocs/3.0/changelog/', 'en/testdocs/3.0/changelog/',
'en/testdocs/3.0/tutorials/', '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 // 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->assertEquals($response->getStatusCode(), 200, 'Existing base folder');
$this->assertContains('english test', $response->getBody(), 'Toplevel content page'); $this->assertContains('english test', $response->getBody(), 'Toplevel content page');
// accessing 2.4 is redirects to the version without the version number. // accessing base redirects to the version with the version number.
$response = $this->get('dev/docs/en/doc_test/2.4/'); $response = $this->get('dev/docs/en/doc_test/');
$this->assertEquals($response->getStatusCode(), 404, 'Existing base folder redirects to without version'); $this->assertEquals($response->getStatusCode(), 301, 'Existing base folder redirects to with version');
$response = $this->get('dev/docs/en/doc_test/3.0/'); $response = $this->get('dev/docs/en/doc_test/3.0/');
$this->assertEquals($response->getStatusCode(), 200, 'Existing base folder'); $this->assertEquals($response->getStatusCode(), 200, 'Existing base folder');
@ -156,7 +156,7 @@ class DocumentationViewerTest extends FunctionalTest {
$this->assertEquals($expected, $actual); $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); $this->assertEquals('current', $v->getMenu()->first()->LinkingMode);
// 2.4 stable release has 1 child page (not including index) // 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 // menu should contain all the english entities
$expected = array( $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/documentationvieweraltmodule1/' => 'DocumentationViewerAltModule1',
'dev/docs/en/documentationvieweraltmodule2/' => 'DocumentationViewerAltModule2' 'dev/docs/en/documentationvieweraltmodule2/' => 'DocumentationViewerAltModule2'
); );
$this->assertEquals($expected, $v->getMenu()->map('Link', 'Title')); $this->assertEquals($expected, $v->getMenu()->map('Link', 'Title'));
} }