Compare commits

...

41 Commits

Author SHA1 Message Date
Maxime Rainville 71d7345a3b
Merge pull request #157 from creative-commoners/pulls/master/abandoned
Mark as abandoned
2023-03-17 10:29:18 +13:00
Guy Sartorelli 446bb12a88
Mark as abandoned 2023-03-17 10:26:53 +13:00
Guy Marriott 619d3e9dd7
Merge branch '2' 2019-08-01 14:23:29 +12:00
Guy Marriott de147fb1a2
Merge branch '2.0' into 2 2019-08-01 14:23:12 +12:00
Guy Marriott 5e8b45f200
Update Travis config 2019-08-01 14:22:53 +12:00
Mateusz Uzdowski 8d1523346e
jQuery 3 compatibility. 2019-08-01 14:22:53 +12:00
Guy Marriott fc7c658b00
jQuery 3 compatibility. (#153)
jQuery 3 compatibility.

Co-authored-by: Guy Marriott <guy@scopey.co.nz>
2019-08-01 14:03:16 +12:00
Guy Marriott a5f7e6f22d
Update Travis config 2019-08-01 14:01:07 +12:00
Mateusz Uzdowski f259e97e13 jQuery 3 compatibility. 2019-08-01 13:55:00 +12:00
Robbie Averill eba2d4536c Update branch alias for master to 3.x-dev 2019-04-29 16:57:06 +12:00
Robbie Averill 5f7a4f7e23 Merge branch '2' 2019-04-29 16:56:49 +12:00
Robbie Averill a539c38091 Remove obsolete branch alias 2019-04-29 16:56:22 +12:00
Robbie Averill 57857836e9 Merge branch '2.0' 2019-02-14 17:43:43 +07:00
Robbie Averill 6dd75a2884 Remove obsolete branch alias 2019-02-14 17:43:28 +07:00
Guy Marriott 171652b338
Merge pull request #151 from creative-commoners/pulls/2.0/extensible-edit-link
FIX getEditLink is now extensible and Lang route handling has a fallback
2019-02-14 20:56:02 +13:00
Robbie Averill e0c20ddf2b FIX getEditLink is now extensible and Lang route handling has a fallback
In some cases the Lang is not available in the route, this fixes that as well as
making the getEditLink() method extensible
2019-02-01 12:19:52 +03:00
Sam Minnee 03ec3d287e MINOR: Alias dev-master as 2.x 2018-06-08 16:14:53 +12:00
Ingo Schommer 8f7ebf42a0
Merge pull request #148 from sminnee/safe-urls
NEW: Ensure internal URLs are domain-relative
2018-06-08 13:26:29 +12:00
Sam Minnee f7377865d4 NEW: Ensure internal URLs are domain-relative
Domain relative URLs (i.e. those starting with “/“) are safer; less
likely to break webcrawlers. Other parts of SilverStripe output URLs
in this form by default.
2018-06-08 11:18:39 +12:00
Sam Minnée 691f5dddb8
FIX: Relaxed parsedown requirement for PHP 7 support (#138)
FIX: Modernise travis build matrix
 - SS 3.6 works with PHP 7.1
 - PHP 5.3 testing is no longer feasible
* FIX: Drop use of precise.

Precise is deprecated, we shouldn’t use it. Instead we should drop php
5.3 testing.
2018-06-08 11:16:16 +12:00
Sam Minnee e28613b1be FIX: Modernise travis build matrix
- SS 3.6 works with PHP 7.1
 - PHP 5.3 testing is no longer feasible
 - Deprecated use of precise no longer needed
2018-06-08 11:15:33 +12:00
Petar Simic e8ab218ffc FIX: Relax parsedown / parsedown-extra requirement, for PHP7 support
Dependency for parsedown increased to minor semver version ~1.1 . Reason: other modules that require parsedown as dependency need higher version of it.
2018-06-08 11:14:56 +12:00
Robbie Averill 2600e55047
Merge pull request #146 from creative-commoners/pulls/2.0/fix-image-float
FIX Remove image styles - revert to original
2018-01-29 13:44:30 +13:00
Sacha Judd 4b18922674 FIX Remove image float 2018-01-29 11:30:30 +13:00
Dylan Wagstaff fccde14751
Merge pull request #144 from creative-commoners/pulls/2.0/fix-canonical-redirects
FIX Ensure first processed stable version is treated as canonical
2017-11-13 14:08:23 +13:00
Robbie Averill d51ece7308 FIX Ensure first processed stable version is treated as canonical 2017-11-10 15:50:03 +13:00
Robbie Averill b8cfbc204e Merge pull request #142 from creative-commoners/pulls/2.0/alert-color
FIX Change alert warning colours
2017-09-07 17:04:18 +12:00
Sacha Judd eae8c0e571 FIX Change alert warning colours 2017-09-07 16:54:12 +12:00
Franco Springveldt 7d22660989 Merge pull request #137 from creative-commoners/pulls/2.0/psr2
Apply PSR-2 coding conventions
2017-09-07 15:38:53 +12:00
Robbie Averill 42f57bc67e Merge pull request #141 from creative-commoners/pulls/2.0/phase-two-accessibility
FIX Add missing web accessible colours and fix image alignment
2017-09-07 09:39:15 +12:00
Robbie Averill ff15115d5e Use precise distro in Travis (PHP 5.3 support) 2017-09-07 09:39:04 +12:00
Sacha Judd 1784471238 FIX Add missing web accessible colours and fix image alignment 2017-09-05 15:11:17 +12:00
Robbie Averill 83594bdf77 Merge pull request #140 from creative-commoners/pulls/2.0/code-blocks-accessibility
NEW Adjust docs colours to be web accessible
2017-08-30 13:57:52 +12:00
Sacha Judd 658c7fe95e NEW Adjust docs colours to be web accessible 2017-08-30 12:37:43 +12:00
Robbie Averill c1a418edfa Merge pull request #139 from creative-commoners/pulls/2.0/link-colour
NEW Change link and code text colours for readability
2017-08-28 11:37:44 +12:00
Robbie Averill fe8b9a37b5 Apply PSR-2 coding conventions 2017-08-28 11:35:02 +12:00
Sacha Judd 9155ca8c85 NEW Change link and code text colours for readability 2017-08-28 11:33:42 +12:00
Franco Springveldt a10cdd35f7 Merge pull request #136 from creative-commoners/pulls/2.0/canonical-url
NEW Add ability to handle canonical URLs
2017-08-14 16:33:49 +12:00
Robbie Averill 4aad4e728d NEW Add ability to handle canonical URLs 2017-08-08 15:41:27 +12:00
Robbie Averill 9521e6ab9d Merge pull request #135 from mateusz/fix-head
Fix docs not coming up for HEAD requests.
2017-07-07 10:33:06 +12:00
Mateusz Uzdowski e90ee42f05 Fix docs not coming up for HEAD requests. 2017-07-07 10:29:48 +12:00
28 changed files with 398 additions and 233 deletions

View File

@ -1,29 +1,26 @@
# See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details
# See https://github.com/silverstripe/silverstripe-travis-support for setup details
sudo: false
dist: trusty
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- 7.0
env:
- DB=MYSQL CORE_RELEASE=3
- DB=MYSQL CORE_RELEASE=3.7
matrix:
allow_failures:
- php: 7.0
include:
- php: '7.1'
env: DB=MYSQL CORE_RELEASE=3.7
- php: '7.2'
env: DB=MYSQL CORE_RELEASE=3.7
- php: '7.3'
env: DB=MYSQL CORE_RELEASE=3.7
before_script:
- composer self-update || true
- git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
- git clone git://github.com/silverstripe/silverstripe-travis-support.git ~/travis-support
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss
- cd ~/builds/ss
- composer install
script:
- vendor/bin/phpunit docsviewer/tests

View File

@ -1,5 +1,9 @@
# Documentation Viewer Module
## ABANDONED
This package is abandoned. See [silverstripe/doc.silverstripe.org](https://github.com/silverstripe/doc.silverstripe.org) instead.
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-docsviewer.png?branch=master)](http://travis-ci.org/silverstripe/silverstripe-docsviewer)
## Maintainer Contact

View File

@ -8,7 +8,7 @@
class DocumentationHelper
{
/**
* String helper for cleaning a file name to a readable version.
* String helper for cleaning a file name to a readable version.
*
* @param string $name to convert
*
@ -95,9 +95,9 @@ class DocumentationHelper
/**
* Helper function to normalize paths to unix style directory separators
*
*
* @param string
*
*
* @return string
*/
public static function normalizePath($path)
@ -111,9 +111,9 @@ class DocumentationHelper
/**
* Helper function to make normalized paths relative
*
*
* @param string
*
*
* @return string
*/
public static function relativePath($path)

View File

@ -90,7 +90,9 @@ class DocumentationManifest
$this->registeredEntities = new ArrayList();
$this->cache = SS_Cache::factory(
'DocumentationManifest', 'Core', array(
'DocumentationManifest',
'Core',
array(
'automatic_serialization' => true,
'lifetime' => null
)
@ -159,7 +161,8 @@ class DocumentationManifest
* @var DocumentationEntity $entity
*/
$entity = Injector::inst()->create(
'DocumentationEntity', $key
'DocumentationEntity',
$key
);
$entity->setPath(DocumentationHelper::normalizePath(Controller::join_links($path, $lang, '/')));
@ -242,7 +245,9 @@ class DocumentationManifest
}
Config::inst()->update(
'DocumentationManifest', 'register_entities', $entities
'DocumentationManifest',
'register_entities',
$entities
);
$this->automaticallyPopulated = true;
@ -371,7 +376,8 @@ class DocumentationManifest
foreach ($grouped as $entity) {
uasort(
$entity, function ($a, $b) {
$entity,
function ($a, $b) {
// ensure parent directories are first
$a['filepath'] = str_replace('index.md', '', $a['filepath']);
$b['filepath'] = str_replace('index.md', '', $b['filepath']);
@ -412,13 +418,15 @@ class DocumentationManifest
*/
protected function stripLinkBase($link)
{
return ltrim(
str_replace(
Config::inst()->get('DocumentationViewer', 'link_base'),
'',
$link
), '/'
);
// Trim baseURL
$link = preg_replace('/^' . preg_quote(Director::baseURL(), '/') .'/', '', $link);
// Trim link_base
if ($linkBase = Config::inst()->get('DocumentationViewer', 'link_base')) {
$link = preg_replace('/^' . preg_quote($linkBase, '/') .'\/?/', '', $link);
}
return $link;
}
/**
@ -452,7 +460,12 @@ class DocumentationManifest
{
$fromLink = $this->stripLinkBase($from);
$toLink = $this->stripLinkBase($to);
$this->redirects[$fromLink] = $toLink;
// If the redirect "from" is already registered with a "to", don't override it. This ensures
// that the first version processed is treated as the canonical version.
if (!isset($this->redirects[$fromLink])) {
$this->redirects[$fromLink] = $toLink;
}
}
/**
@ -461,7 +474,10 @@ class DocumentationManifest
public function handleFolder($basename, $path, $depth)
{
$folder = Injector::inst()->create(
'DocumentationFolder', $this->entity, $basename, $path
'DocumentationFolder',
$this->entity,
$basename,
$path
);
// Add main folder link
@ -491,7 +507,9 @@ class DocumentationManifest
{
$page = Injector::inst()->create(
'DocumentationPage',
$this->entity, $basename, $path
$this->entity,
$basename,
$path
);
// populate any meta data
@ -552,6 +570,19 @@ class DocumentationManifest
return $output;
}
/**
* Create a clean domain-relative URL form a docuetn URL
*/
protected function buildUrl($url)
{
return Controller::join_links(
Director::baseURL(),
Config::inst()->get('DocumentationViewer', 'link_base'),
$url,
'/'
);
}
/**
* Determine the next page from the given page.
*
@ -572,7 +603,7 @@ class DocumentationManifest
if ($grabNext && strpos($page['filepath'], $entityBase) !== false) {
return new ArrayData(
array(
'Link' => Controller::join_links(Config::inst()->get('DocumentationViewer', 'link_base'), $url),
'Link' => $this->buildUrl($url),
'Title' => $page['title']
)
);
@ -583,7 +614,7 @@ class DocumentationManifest
} elseif (!$fallback && strpos($page['filepath'], $filepath) !== false) {
$fallback = new ArrayData(
array(
'Link' => Controller::join_links(Config::inst()->get('DocumentationViewer', 'link_base'), $url),
'Link' => $this->buildUrl($url),
'Title' => $page['title'],
'Fallback' => true
)
@ -618,7 +649,7 @@ class DocumentationManifest
if ($previousUrl) {
return new ArrayData(
array(
'Link' => Controller::join_links(Config::inst()->get('DocumentationViewer', 'link_base'), $previousUrl),
'Link' => $this->buildUrl($previousUrl),
'Title' => $previousPage['title']
)
);
@ -667,7 +698,6 @@ class DocumentationManifest
}
$output = new ArrayList();
$base = Config::inst()->get('DocumentationViewer', 'link_base');
$entityPath = $this->normalizeUrl($entityPath);
$recordPath = $this->normalizeUrl($recordPath);
$recordParts = explode('/', trim($recordPath, '/'));
@ -703,7 +733,7 @@ class DocumentationManifest
$output->push(
new ArrayData(
array(
'Link' => Controller::join_links($base, $url, '/'),
'Link' => $this->buildUrl($url),
'Title' => $page['title'],
'LinkingMode' => $mode,
'Summary' => $page['summary'],

View File

@ -21,7 +21,7 @@ class DocumentationManifestFileFinder extends SS_FileFinder
);
/**
*
*
*/
public function acceptDir($basename, $pathname, $depth)
{

View File

@ -125,7 +125,6 @@ class DocumentationParser
$inner = true;
}
} elseif (preg_match('/^[\ ]{0,3}?[\t](.*)/', $line, $matches)) {
// inner line of block, or first line of standard markdown code block
// regex removes first tab (any following tabs are part of the code).
if (!$started) {
@ -248,7 +247,9 @@ class DocumentationParser
if (substr($url, 0, 1) == '/') {
$relativeUrl = DocumentationHelper::normalizePath(
str_replace(
BASE_PATH, '', Controller::join_links(
BASE_PATH,
'',
Controller::join_links(
$page->getEntity()->getPath(),
$url
)
@ -326,11 +327,11 @@ class DocumentationParser
$html_format = '<a href="http://api.silverstripe.org/search/lookup/?q=%s&version=%s&module=%s">%s</a>';
// parse api links without backticks into html
foreach($regexs as $type => $regex) {
foreach ($regexs as $type => $regex) {
preg_match_all($regex, $markdown, $links);
if($links) {
foreach($links[0] as $i => $match) {
if($type === 'no_title') {
if ($links) {
foreach ($links[0] as $i => $match) {
if ($type === 'no_title') {
$title = $links[1][$i];
$link = $links[1][$i];
// change backticked links to avoid being parsed in the same way as non-backticked links
@ -349,8 +350,8 @@ class DocumentationParser
// recover backticked links with no titles
preg_match_all('#XYZ(.*)?XYZ#', $markdown, $links);
if($links) {
foreach($links[0] as $i => $match) {
if ($links) {
foreach ($links[0] as $i => $match) {
$link = $links[1][$i];
$markdown = str_replace($match, '`[api:'.$link.']`', $markdown);
}
@ -358,8 +359,8 @@ class DocumentationParser
// recover backticked links with titles
preg_match_all('#XX(.*)?YY(.*)?ZZ#', $markdown, $links);
if($links) {
foreach($links[0] as $i => $match) {
if ($links) {
foreach ($links[0] as $i => $match) {
$title = $links[1][$i];
$link = $links[2][$i];
$markdown = str_replace($match, '`['.$title.'](api:'.$link.')`', $markdown);
@ -367,7 +368,6 @@ class DocumentationParser
}
return $markdown;
}
/**
@ -488,7 +488,7 @@ class DocumentationParser
$fileBaseLink,
$url
);
} else if (preg_match('/^#/', $url)) {
} elseif (preg_match('/^#/', $url)) {
// for relative links begining with a hash use the current page link
$relativeUrl = Controller::join_links($baselink, $page->getRelativeLink(), $url);
} else {
@ -521,5 +521,4 @@ class DocumentationParser
return $md;
}
}

View File

@ -1,7 +1,7 @@
<?php
/**
* A mapping store of given permalinks to the full documentation path or useful
* A mapping store of given permalinks to the full documentation path or useful
* for customizing the shortcut URLs used in the viewer.
*
* Redirects the user from example.com/foo to example.com/en/module/foo
@ -25,7 +25,7 @@ class DocumentationPermalinks
* ));
* </code>
*
* Do not need to include the language or the version current as it
* Do not need to include the language or the version current as it
* will add it based off the language or version in the session
*
* @param array

View File

@ -8,20 +8,20 @@ set_include_path(
require_once 'Zend/Search/Lucene.php';
/**
* Documentation Search powered by Lucene. You will need Zend_Lucene installed
* Documentation Search powered by Lucene. You will need Zend_Lucene installed
* on your path.
*
* To rebuild the indexes run the {@link RebuildLuceneDocsIndex} task. You may
* To rebuild the indexes run the {@link RebuildLuceneDocsIndex} task. You may
* wish to setup a cron job to remake the indexes on a regular basis.
*
* This class has the ability to generate an OpenSearch RSS formatted feeds
* This class has the ability to generate an OpenSearch RSS formatted feeds
* simply by using the URL:
*
* <code>
* yoursite.com/search/?q=Foo&format=rss. // Format can either be specified as rss or left off.
* </code>
*
* To get a specific amount of results you can also use the modifiers start and
* To get a specific amount of results you can also use the modifiers start and
* limit:
*
* <code>
@ -127,7 +127,7 @@ class DocumentationSearch
* Folder name for indexes (in the temp folder).
*
* @config
* @var string
* @var string
*/
private static $index_location;
@ -363,7 +363,7 @@ class DocumentationSearch
}
/**
* OpenSearch MetaData fields. For a list of fields consult
* OpenSearch MetaData fields. For a list of fields consult
* {@link self::get_meta_data()}
*
* @param array
@ -406,7 +406,7 @@ class DocumentationSearch
}
/**
* Renders the search results into a template. Either the search results
* Renders the search results into a template. Either the search results
* template or the Atom feed.
*/
public function renderResults()
@ -428,7 +428,8 @@ class DocumentationSearch
$title = ($title = $this->getTitle()) ? ' - '. $title : "";
$link = Controller::join_links(
$this->outputController->Link(), 'DocumentationOpenSearchController/description/'
$this->outputController->Link(),
'DocumentationOpenSearchController/description/'
);
$data->setField('Title', $data->Title . $title);

View File

@ -62,7 +62,7 @@ class DocumentationViewer extends Controller implements PermissionProvider
/**
* @config
*
* @var string same as the routing pattern set through Director::addRules().
* @var string Site-relative root URL of documentation. Same as the routing pattern set through Director::addRules().
*/
private static $link_base = 'dev/docs/';
@ -110,7 +110,7 @@ class DocumentationViewer extends Controller implements PermissionProvider
)
);
Requirements::combine_files(
'docs.css',
'docs.css',
array(
DOCSVIEWER_DIR .'/css/highlight.css',
DOCSVIEWER_DIR .'/css/normalize.css',
@ -177,7 +177,7 @@ class DocumentationViewer extends Controller implements PermissionProvider
public function handleAction($request, $action)
{
// if we submitted a form, let that pass
if (!$request->isGET()) {
if (!$request->isGET() && !$request->isHEAD()) {
return parent::handleAction($request, $action);
}
@ -204,7 +204,8 @@ class DocumentationViewer extends Controller implements PermissionProvider
// Strip off the base url
//
$base = ltrim(
Config::inst()->get('DocumentationViewer', 'link_base'), '/'
Config::inst()->get('DocumentationViewer', 'link_base'),
'/'
);
if ($base && strpos($url, $base) !== false) {
@ -212,7 +213,6 @@ class DocumentationViewer extends Controller implements PermissionProvider
ltrim($url, '/'),
strlen($base)
);
} else {
}
//
@ -275,6 +275,11 @@ class DocumentationViewer extends Controller implements PermissionProvider
// return $redirect->redirect($cleaned, 302);
// }
if ($record = $this->getManifest()->getPage($url)) {
// In SS 3 offsetSet() isn't implemented for some reason... this is a workaround
$routeParams = $this->request->routeParams();
$routeParams['Lang'] = $lang;
$this->request->setRouteParams($routeParams);
$this->record = $record;
$this->init();
@ -393,7 +398,8 @@ class DocumentationViewer extends Controller implements PermissionProvider
// add children
$children = $this->getManifest()->getChildrenFor(
$entity->getPath(), ($record) ? $record->getPath() : $entity->getPath()
$entity->getPath(),
($record) ? $record->getPath() : $entity->getPath()
);
} else {
if ($current && $current->getKey() == $entity->getKey()) {
@ -438,7 +444,7 @@ class DocumentationViewer extends Controller implements PermissionProvider
public function replaceChildrenCalls($html)
{
$codes = new ShortcodeParser();
$codes->register('CHILDREN', array($this, 'includeChildren'));
$codes->register('CHILDREN', array($this, 'includeChildren'));
return $codes->parse($html);
}
@ -565,6 +571,7 @@ class DocumentationViewer extends Controller implements PermissionProvider
public function Link($action = '')
{
$link = Controller::join_links(
Director::baseURL(),
Config::inst()->get('DocumentationViewer', 'link_base'),
$this->getLanguage(),
$action,
@ -574,6 +581,19 @@ class DocumentationViewer extends Controller implements PermissionProvider
return $link;
}
/**
* Return the canonical URL from the page
*
* @return string
*/
public function getCanonicalUrl()
{
if (!$this->getPage()) {
return '';
}
return $this->getPage()->getCanonicalUrl();
}
/**
* Generate a list of all the pages in the documentation grouped by the
* first letter of the page.
@ -671,17 +691,19 @@ class DocumentationViewer extends Controller implements PermissionProvider
/**
* Returns an edit link to the current page (optional).
*
* @return string
* @return string|false
*/
public function getEditLink()
{
$editLink = false;
$entity = null;
$page = $this->getPage();
if ($page) {
$entity = $page->getEntity();
if ($entity && isset(self::$edit_links[strtolower($entity->title)])) {
// build the edit link, using the version defined
$url = self::$edit_links[strtolower($entity->title)];
$version = $entity->getVersion();
@ -691,13 +713,13 @@ class DocumentationViewer extends Controller implements PermissionProvider
}
if ($version == 'trunk' && (isset($url['options']['rewritetrunktomaster']))) {
if ($version === 'trunk' && (isset($url['options']['rewritetrunktomaster']))) {
if ($url['options']['rewritetrunktomaster']) {
$version = "master";
}
}
return str_replace(
$editLink = str_replace(
array('%entity%', '%lang%', '%version%', '%path%'),
array(
$entity->title,
@ -710,7 +732,9 @@ class DocumentationViewer extends Controller implements PermissionProvider
}
}
return false;
$this->extend('updateDocumentationEditLink', $editLink, $entity);
return $editLink;
}
@ -725,7 +749,8 @@ class DocumentationViewer extends Controller implements PermissionProvider
{
return ($this->record)
? $this->getManifest()->getNextPage(
$this->record->getPath(), $this->getEntity()->getPath()
$this->record->getPath(),
$this->getEntity()->getPath()
)
: null;
}
@ -740,7 +765,8 @@ class DocumentationViewer extends Controller implements PermissionProvider
{
return ($this->record)
? $this->getManifest()->getPreviousPage(
$this->record->getPath(), $this->getEntity()->getPath()
$this->record->getPath(),
$this->getEntity()->getPath()
)
: null;
}
@ -770,7 +796,10 @@ class DocumentationViewer extends Controller implements PermissionProvider
*/
public function getDocumentationBaseHref()
{
return Config::inst()->get('DocumentationViewer', 'link_base');
return Controller::join_links(
Director::baseURL(),
Config::inst()->get('DocumentationViewer', 'link_base')
);
}
/**

View File

@ -34,7 +34,8 @@ class DocumentationAdvancedSearchForm extends Form
CheckboxSetField::create(
'Versions',
_t('DocumentationViewer.VERSIONS', 'Versions'),
$versions, $searchedVersions
$versions,
$searchedVersions
)
);

View File

@ -137,12 +137,14 @@ class DocumentationEntity extends ViewableData
{
if ($this->getIsDefaultEntity()) {
$base = Controller::join_links(
Director::baseURL(),
Config::inst()->get('DocumentationViewer', 'link_base'),
$this->getLanguage(),
'/'
);
} else {
$base = Controller::join_links(
Director::baseURL(),
Config::inst()->get('DocumentationViewer', 'link_base'),
$this->getLanguage(),
$this->getKey(),
@ -150,8 +152,6 @@ class DocumentationEntity extends ViewableData
);
}
$base = ltrim(str_replace('//', '/', $base), '/');
if ($short && $this->stable) {
return $base;
}

View File

@ -1,9 +1,9 @@
<?php
/**
* A specific documentation folder within a {@link DocumentationEntity}.
* A specific documentation folder within a {@link DocumentationEntity}.
*
* Maps to a folder on the file system.
* Maps to a folder on the file system.
*
* @package docsviewer
* @subpackage model

View File

@ -38,6 +38,11 @@ class DocumentationPage extends ViewableData
protected $read = false;
/**
* @var string
*/
protected $canonicalUrl;
/**
* @param DocumentationEntity $entity
* @param string $filename
@ -82,7 +87,8 @@ class DocumentationPage extends ViewableData
);
$titleParts = array_filter(
$titleParts, function ($val) {
$titleParts,
function ($val) {
if ($val) {
return $val;
}
@ -256,14 +262,26 @@ class DocumentationPage extends ViewableData
*/
public function Link($short = false)
{
return ltrim(
Controller::join_links(
$this->entity->Link($short),
$this->getRelativeLink()
), '/'
return Controller::join_links(
$this->entity->Link($short),
$this->getRelativeLink()
);
}
/**
* Determine and set the canonical URL for the given record, for example: dev/docs/en/Path/To/Document
*/
public function populateCanonicalUrl()
{
$url = Director::absoluteURL(Controller::join_links(
Config::inst()->get('DocumentationViewer', 'link_base'),
$this->getEntity()->getLanguage(),
$this->getRelativeLink()
));
$this->setCanonicalUrl($url);
}
/**
* Return metadata from the first html block in the page, then remove the
* block on request
@ -349,5 +367,30 @@ class DocumentationPage extends ViewableData
{
return sprintf(get_class($this) .': %s)', $this->getPath());
}
}
/**
* Set the canonical URL to use for this page
*
* @param string $canonicalUrl
* @return $this
*/
public function setCanonicalUrl($canonicalUrl)
{
$this->canonicalUrl = $canonicalUrl;
return $this;
}
/**
* Get the canonical URL to use for this page. Will trigger discovery
* via {@link DocumentationPage::populateCanonicalUrl()} if none is already set.
*
* @return string
*/
public function getCanonicalUrl()
{
if (!$this->canonicalUrl) {
$this->populateCanonicalUrl();
}
return $this->canonicalUrl;
}
}

View File

@ -10,16 +10,16 @@ class CheckDocsSourcesTask extends BuildTask
protected $description = "Check validity of all docs source files registered";
public function start()
public function start()
{
if(!Director::is_cli()) {
if (!Director::is_cli()) {
echo "<ul>";
}
}
public function end()
public function end()
{
if(Director::is_cli()) {
if (Director::is_cli()) {
echo "\nTotal errors: {$this->errors}\n";
} else {
echo "</ul>";
@ -27,10 +27,10 @@ class CheckDocsSourcesTask extends BuildTask
}
}
public function showError($error)
public function showError($error)
{
$this->errors++;
if(Director::is_cli()) {
if (Director::is_cli()) {
echo "\n$error";
} else {
echo "<li>" . Convert::raw2xml($error) . "</li>";

View File

@ -1,9 +1,9 @@
<?php
/**
* Rebuilds the search indexes for the documentation pages.
* Rebuilds the search indexes for the documentation pages.
*
* For the hourly cron rebuild use RebuildLuceneDocusIndex_Hourly
* For the hourly cron rebuild use RebuildLuceneDocusIndex_Hourly
*
* @package docsviewer
* @subpackage tasks
@ -87,25 +87,29 @@ class RebuildLuceneDocsIndex extends BuildTask
$doc->addField(
Zend_Search_Lucene_Field::Keyword(
'Version', $page->getEntity()->getVersion()
'Version',
$page->getEntity()->getVersion()
)
);
$doc->addField(
Zend_Search_Lucene_Field::Keyword(
'Language', $page->getEntity()->getLanguage()
'Language',
$page->getEntity()->getLanguage()
)
);
$doc->addField(
Zend_Search_Lucene_Field::Keyword(
'Entity', $page->getEntity()
'Entity',
$page->getEntity()
)
);
$doc->addField(
Zend_Search_Lucene_Field::Keyword(
'Link', $page->Link()
'Link',
$page->Link()
)
);

View File

@ -15,11 +15,17 @@
},
"require": {
"silverstripe/framework": "~3.1",
"erusev/parsedown-extra": "0.2.2",
"erusev/parsedown": "~1.1.0",
"erusev/parsedown-extra": "~0.2",
"erusev/parsedown": "~1.1",
"mnapoli/front-yaml": "^1.5"
},
"suggest": {
"silverstripe/staticpublisher": "Allows publishing documentation as HTML"
}
},
"extra": {
"branch-alias": {
"dev-master": "3.x-dev"
}
},
"abandoned": true
}

View File

@ -8,23 +8,23 @@ Customised for doc.silverstripe.org, see CUSTOM markers.
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
color: #333;
padding: 1.5em 1em;
color: #444;
background: #f3f6f6; /* CUSTOM */
border-radius: 3px; /* CUSTOM */
box-shadow: 0 1px 1px rgba(0,0,0,.125); /* CUSTOM */
box-shadow: 0 1px 3px rgba(0,0,0,.15); /* CUSTOM */
}
.hljs-comment,
.hljs-quote {
color: #998;
color: #717171;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
color: #444;
font-weight: bold;
}
@ -33,12 +33,12 @@ Customised for doc.silverstripe.org, see CUSTOM markers.
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
color: #007e7e;
}
.hljs-string,
.hljs-doctag {
color: #d14;
color: #ed135a;
}
.hljs-title,
@ -67,7 +67,7 @@ Customised for doc.silverstripe.org, see CUSTOM markers.
.hljs-regexp,
.hljs-link {
color: #009926;
color: #008500;
}
.hljs-symbol,

View File

@ -298,14 +298,6 @@ html {
padding: 0 30px;
}
#footer p {
color: #798D85;
}
#footer p a {
color: #798D85;
}
/*! Pagination */
#page-numbers span,
#page-numbers a {
@ -476,35 +468,23 @@ html {
text-align: center;
}
.info,
.notice,
.note,
.warningBox {
background: #FFFFAD;
.warningBox,
form .message.good {
background: #e6f5fc;
}
.warning,
.alert {
background: #FF8480;
color:#fff;
}
.warning a,
.alert a {
color:#fff;
text-decoration:underline;
}
.warning code,
.alert code {
color:#666;
.alert,
form .message.error {
background: #f2dede;
color: #a94442;
}
.hint {
background: #f4f4f4;
}
.info {
background: #CAF7FF;
background: #f0f4f4;
}
.warning p {
@ -638,7 +618,7 @@ html {
}
.next-prev a {
color: #798D85;
color: #586667;
}
.next-prev p {

View File

@ -13,7 +13,7 @@
/*! links */
a {
color: #808c8d;
color: #0071c4;
text-decoration: none;
}
@ -164,7 +164,7 @@ h3 {
font-size: 20px;
line-height: 20px;
margin: 30px 0 10px;
color: #181c1d;
color: #586667;
}
h4 {
@ -223,21 +223,23 @@ pre {
pre code {
/* reset block styles */
font-size: 1em;
font-size: 1em;
line-height: 1.5em;
}
code {
code {
/* inline styles, fit with non-code text */
font-size: 13px;
line-height: 15px;
font-family: Monaco, 'Bitstream Vera Sans Mono', Courier, monospace;
background: #f3f6f6;
padding: 2px;
}
code a {
color: #4E5661;
font-family: Monaco, 'Bitstream Vera Sans Mono', Courier, monospace;
background: #f0f4f4;
color: #ed135a;
padding: 2px;
}
code a {
color: #ed135a;
text-decoration: underline;
}
/*! quotes */
@ -330,7 +332,7 @@ table {
border: 1px solid #d4d4d4;
border-bottom-color: #bcbcbc;
text-shadow: 0 1px 0 #fff;
color: #333;
color: #444;
font-weight: bold;
margin-bottom: 5px;
text-decoration: none;

View File

@ -55,7 +55,7 @@
}
};
$(window).load(updateTables);
$(window).on('load', updateTables);
$(window).on(
"redraw",function() {
switched = false;

View File

@ -2,6 +2,9 @@
<% base_tag %>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<% if $CanonicalUrl %>
<link rel="canonical" href="$CanonicalUrl" />
<% end_if %>
<title><% if Title %>$Title &#8211; <% end_if %>$DocumentationTitle</title>
</head>

View File

@ -2,7 +2,7 @@
class DocumentationEntityTest extends SapphireTest
{
public function dataCompare()
public function dataCompare()
{
return array(
array('3', '3.0', 1),
@ -20,7 +20,7 @@ class DocumentationEntityTest extends SapphireTest
* @param string $right
* @param int $result
*/
public function testCompare($left, $right, $result)
public function testCompare($left, $right, $result)
{
$leftVersion = new DocumentationEntity('Framework');
$leftVersion->setVersion($left);

View File

@ -16,18 +16,24 @@ class DocumentationManifestTests extends SapphireTest
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update(
'DocumentationViewer', 'link_base', 'dev/docs'
'DocumentationViewer',
'link_base',
'dev/docs'
);
// disable automatic module registration so modules don't interfere.
Config::inst()->update(
'DocumentationManifest', 'automatic_registration', false
'DocumentationManifest',
'automatic_registration',
false
);
Config::inst()->remove('DocumentationManifest', 'register_entities');
Config::inst()->update(
'DocumentationManifest', 'register_entities', array(
'DocumentationManifest',
'register_entities',
array(
array(
'Path' => DOCSVIEWER_PATH . "/tests/docs/",
'Title' => 'Doc Test',
@ -189,7 +195,8 @@ class DocumentationManifestTests extends SapphireTest
);
$this->assertDOSContains(
$expected, $this->manifest->getChildrenFor(
$expected,
$this->manifest->getChildrenFor(
DOCSVIEWER_PATH . '/tests/docs/en/'
)
);

View File

@ -19,10 +19,8 @@ class DocumentationPageTest extends SapphireTest
Config::nest();
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update(
'DocumentationViewer', 'link_base', 'dev/docs/'
);
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update('DocumentationViewer', 'link_base', 'dev/docs/');
$manifest = new DocumentationManifest(true);
}
@ -41,10 +39,11 @@ class DocumentationPageTest extends SapphireTest
'test.md',
DOCSVIEWER_PATH . '/tests/docs/en/test.md'
);
// single layer
$this->assertEquals(
'dev/docs/en/doctest/2.4/test/', $page->Link(),
Director::baseURL() . 'dev/docs/en/doctest/2.4/test/',
$page->Link(),
'The page link should have no extension and have a language'
);
@ -53,18 +52,18 @@ class DocumentationPageTest extends SapphireTest
'sort',
DOCSVIEWER_PATH . '/tests/docs/en/sort/'
);
$this->assertEquals('dev/docs/en/doctest/2.4/sort/', $page->Link());
$this->assertEquals(Director::baseURL() . 'dev/docs/en/doctest/2.4/sort/', $page->Link());
$page = new DocumentationFolder(
$this->entity,
'1-basic.md',
DOCSVIEWER_PATH . '/tests/docs/en/sort/1-basic.md'
);
$this->assertEquals('dev/docs/en/doctest/2.4/sort/basic/', $page->Link());
$this->assertEquals(Director::baseURL() . 'dev/docs/en/doctest/2.4/sort/basic/', $page->Link());
}
public function testGetBreadcrumbTitle()
{
$page = new DocumentationPage(
@ -74,13 +73,13 @@ class DocumentationPageTest extends SapphireTest
);
$this->assertEquals("Test - Doctest", $page->getBreadcrumbTitle());
$page = new DocumentationFolder(
$this->entity,
'1-basic.md',
DOCSVIEWER_PATH . '/tests/docs/en/sort/1-basic.md'
);
$this->assertEquals('Basic - Sort - Doctest', $page->getBreadcrumbTitle());
$page = new DocumentationFolder(
@ -91,4 +90,22 @@ class DocumentationPageTest extends SapphireTest
$this->assertEquals('Sort - Doctest', $page->getBreadcrumbTitle());
}
public function testGetCanonicalUrl()
{
$page = new DocumentationPage(
$this->entity,
'file.md',
DOCSVIEWER_PATH . '/tests/docs/en/test/file.md'
);
$this->assertContains(
'dev/docs/en/test/file/',
$page->getCanonicalUrl(),
'Canonical URL is determined, set and returned'
);
$page->setCanonicalUrl('some-other-url');
$this->assertSame('some-other-url', $page->getCanonicalUrl(), 'Canonical URL can be adjusted via public API');
}
}

View File

@ -23,7 +23,9 @@ class DocumentationParserTest extends SapphireTest
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update(
'DocumentationViewer', 'link_base', 'dev/docs/'
'DocumentationViewer',
'link_base',
'dev/docs/'
);
$this->entity = new DocumentationEntity('DocumentationParserTest');
@ -172,7 +174,7 @@ HTML;
);
$this->assertContains(
'[link: subfolder index](dev/docs/en/documentationparsertest/2.4/subfolder/)',
'[link: subfolder index](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/subfolder/)',
$result
);
@ -184,11 +186,11 @@ HTML;
);
$this->assertContains(
'[link: subfolder index](dev/docs/en/documentationparsertest/2.4/subfolder/)',
'[link: subfolder index](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/subfolder/)',
$result
);
$this->assertContains(
'[link: subfolder page](dev/docs/en/documentationparsertest/2.4/subfolder/subpage/)',
'[link: subfolder page](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/subfolder/subpage/)',
$result
);
$this->assertContains(
@ -197,12 +199,12 @@ HTML;
);
$this->assertContains(
'[link: with anchor](dev/docs/en/documentationparsertest/2.4/test/#anchor)',
'[link: with anchor](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/test/#anchor)',
$result
);
$this->assertContains(
'[link: relative anchor](dev/docs/en/documentationparsertest/2.4/test/#relative-anchor)',
'[link: relative anchor](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/test/#relative-anchor)',
$result
);
@ -213,33 +215,33 @@ HTML;
// @todo this should redirect to /subpage/
$this->assertContains(
'[link: relative](dev/docs/en/documentationparsertest/2.4/subfolder/subpage.md/)',
'[link: relative](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/subfolder/subpage.md/)',
$result
);
$this->assertContains(
'[link: absolute index](dev/docs/en/documentationparsertest/2.4/)',
'[link: absolute index](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/)',
$result
);
// @todo this should redirect to /
$this->assertContains(
'[link: absolute index with name](dev/docs/en/documentationparsertest/2.4/index/)',
'[link: absolute index with name](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/index/)',
$result
);
$this->assertContains(
'[link: relative index](dev/docs/en/documentationparsertest/2.4/)',
'[link: relative index](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/)',
$result
);
$this->assertContains(
'[link: relative parent page](dev/docs/en/documentationparsertest/2.4/test/)',
'[link: relative parent page](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/test/)',
$result
);
$this->assertContains(
'[link: absolute parent page](dev/docs/en/documentationparsertest/2.4/test/)',
'[link: absolute parent page](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/test/)',
$result
);
@ -249,27 +251,27 @@ HTML;
);
$this->assertContains(
'[link: absolute index](dev/docs/en/documentationparsertest/2.4/)',
'[link: absolute index](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/)',
$result
);
$this->assertContains(
'[link: relative index](dev/docs/en/documentationparsertest/2.4/subfolder/)',
'[link: relative index](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/subfolder/)',
$result
);
$this->assertContains(
'[link: relative parent page](dev/docs/en/documentationparsertest/2.4/subfolder/subpage/)',
'[link: relative parent page](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/subfolder/subpage/)',
$result
);
$this->assertContains(
'[link: relative grandparent page](dev/docs/en/documentationparsertest/2.4/test/)',
'[link: relative grandparent page](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/test/)',
$result
);
$this->assertContains(
'[link: absolute page](dev/docs/en/documentationparsertest/2.4/test/)',
'[link: absolute page](' . Director::baseURL() . 'dev/docs/en/documentationparsertest/2.4/test/)',
$result
);
}
@ -294,7 +296,9 @@ HTML;
);
$expected = Controller::join_links(
Director::absoluteBaseURL(), DOCSVIEWER_DIR, '/tests/docs/en/subfolder/_images/image.png'
Director::absoluteBaseURL(),
DOCSVIEWER_DIR,
'/tests/docs/en/subfolder/_images/image.png'
);
$this->assertContains(
@ -304,15 +308,20 @@ HTML;
$this->assertContains(
sprintf(
'[parent image link](%s)', Controller::join_links(
Director::absoluteBaseURL(), DOCSVIEWER_DIR, '/tests/docs/en/_images/image.png'
'[parent image link](%s)',
Controller::join_links(
Director::absoluteBaseURL(),
DOCSVIEWER_DIR,
'/tests/docs/en/_images/image.png'
)
),
$result
);
$expected = Controller::join_links(
Director::absoluteBaseURL(), DOCSVIEWER_DIR, '/tests/docs/en/_images/image.png'
Director::absoluteBaseURL(),
DOCSVIEWER_DIR,
'/tests/docs/en/_images/image.png'
);
$this->assertContains(
@ -350,11 +359,10 @@ HTML;
array('[Title](api:DataObject::populateDefaults())',sprintf($html_format, 'DataObject::populateDefaults()', 'Title'))
);
foreach($test_cases as $test_case) {
foreach ($test_cases as $test_case) {
$expected_html = $test_case[1];
$this->assertContains($expected_html, $parsed_page);
}
}
public function testHeadlineAnchors()

View File

@ -13,20 +13,26 @@ class DocumentationSearchTest extends FunctionalTest
Config::nest();
// explicitly use dev/docs. Custom paths should be tested separately
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update(
'DocumentationViewer', 'link_base', 'dev/docs'
'DocumentationViewer',
'link_base',
'dev/docs'
);
// disable automatic module registration so modules don't interfere.
Config::inst()->update(
'DocumentationManifest', 'automatic_registration', false
'DocumentationManifest',
'automatic_registration',
false
);
Config::inst()->remove('DocumentationManifest', 'register_entities');
Config::inst()->update('DocumentationSearch', 'enabled', true);
Config::inst()->update(
'DocumentationManifest', 'register_entities', array(
'DocumentationManifest',
'register_entities',
array(
array(
'Path' => DOCSVIEWER_PATH . "/tests/docs-search/",
'Title' => 'Docs Search Test', )
@ -54,8 +60,8 @@ class DocumentationSearchTest extends FunctionalTest
$response = $c->handleRequest(new SS_HTTPRequest('GET', 'description/'), DataModel::inst());
// $this->assertEquals(404, $response->getStatusCode());
// test we get a response to the description. The meta data test will
// check that the individual fields are valid but we should check urls
// test we get a response to the description. The meta data test will
// check that the individual fields are valid but we should check urls
// are there
Config::inst()->update('DocumentationSearch', 'enabled', true);

View File

@ -11,7 +11,7 @@
class DocumentationViewerTest extends FunctionalTest
{
protected $autoFollowRedirection = false;
protected $manifest;
public function setUp()
@ -20,20 +20,26 @@ class DocumentationViewerTest extends FunctionalTest
Config::nest();
// explicitly use dev/docs. Custom paths should be tested separately
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update(
'DocumentationViewer', 'link_base', 'dev/docs/'
'DocumentationViewer',
'link_base',
'dev/docs/'
);
// disable automatic module registration so modules don't interfere.
Config::inst()->update(
'DocumentationManifest', 'automatic_registration', false
'DocumentationManifest',
'automatic_registration',
false
);
Config::inst()->remove('DocumentationManifest', 'register_entities');
Config::inst()->update(
'DocumentationManifest', 'register_entities', array(
'DocumentationManifest',
'register_entities',
array(
array(
'Path' => DOCSVIEWER_PATH . "/tests/docs/",
'Title' => 'Doc Test',
@ -65,11 +71,11 @@ class DocumentationViewerTest extends FunctionalTest
$this->manifest = new DocumentationManifest(true);
}
public function tearDown()
{
parent::tearDown();
Config::unnest();
}
@ -98,47 +104,47 @@ class DocumentationViewerTest extends FunctionalTest
$response = $this->get('dev/docs/en/doc_test/3.0/empty.md');
$this->assertEquals(301, $response->getStatusCode(), 'Direct markdown links also work. They should redirect to /empty/');
// 2.4 is the stable release. Not in the URL
$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 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');
$response = $this->get('dev/docs/en/doc_test/2.3/nonexistant-subfolder');
$this->assertEquals($response->getStatusCode(), 404, 'Nonexistant subfolder');
$response = $this->get('dev/docs/en/doc_test/2.3/nonexistant-file.txt');
$this->assertEquals($response->getStatusCode(), 301, 'Nonexistant file');
$response = $this->get('dev/docs/en/doc_test/2.3/nonexistant-file/');
$this->assertEquals($response->getStatusCode(), 404, 'Nonexistant file');
$response = $this->get('dev/docs/en/doc_test/2.3/test');
$this->assertEquals($response->getStatusCode(), 200, 'Existing file');
$response = $this->get('dev/docs/en/doc_test/3.0/empty?foo');
$this->assertEquals(200, $response->getStatusCode(), 'Existing page');
$response = $this->get('dev/docs/en/doc_test/3.0/empty/');
$this->assertEquals($response->getStatusCode(), 200, 'Existing page');
$response = $this->get('dev/docs/en/doc_test/3.0/test');
$this->assertEquals($response->getStatusCode(), 404, 'Missing page');
$response = $this->get('dev/docs/en/doc_test/3.0/test.md');
$this->assertEquals($response->getStatusCode(), 301, 'Missing page');
$response = $this->get('dev/docs/en/doc_test/3.0/test/');
$this->assertEquals($response->getStatusCode(), 404, 'Missing page');
$response = $this->get('dev/docs/dk/');
$this->assertEquals($response->getStatusCode(), 404, 'Access a language that doesn\'t exist');
}
@ -151,9 +157,9 @@ class DocumentationViewerTest extends FunctionalTest
$response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/doc_test/2.3/'), DataModel::inst());
$expected = array(
'dev/docs/en/doc_test/2.3/sort/' => 'Sort',
'dev/docs/en/doc_test/2.3/subfolder/' => 'Subfolder',
'dev/docs/en/doc_test/2.3/test/' => 'Test'
Director::baseURL() . 'dev/docs/en/doc_test/2.3/sort/' => 'Sort',
Director::baseURL() . 'dev/docs/en/doc_test/2.3/subfolder/' => 'Subfolder',
Director::baseURL() . 'dev/docs/en/doc_test/2.3/test/' => 'Test'
);
$actual = $v->getMenu()->first()->Children->map('Link', 'Title');
@ -168,9 +174,9 @@ class DocumentationViewerTest extends FunctionalTest
// menu should contain all the english entities
$expected = array(
'dev/docs/en/doc_test/2.4/' => 'Doc Test',
'dev/docs/en/documentationvieweraltmodule1/' => 'DocumentationViewerAltModule1',
'dev/docs/en/documentationvieweraltmodule2/' => 'DocumentationViewerAltModule2'
Director::baseURL() . 'dev/docs/en/doc_test/2.4/' => 'Doc Test',
Director::baseURL() . 'dev/docs/en/documentationvieweraltmodule1/' => 'DocumentationViewerAltModule1',
Director::baseURL() . 'dev/docs/en/documentationvieweraltmodule2/' => 'DocumentationViewerAltModule2'
);
$this->assertEquals($expected, $v->getMenu()->map('Link', 'Title'));
@ -188,7 +194,7 @@ class DocumentationViewerTest extends FunctionalTest
$response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/doc_test/2.3/subfolder/subsubfolder/subsubpage/'), DataModel::inst());
$this->assertEquals('en', $v->getLanguage());
}
public function testAccessingAll()
{
@ -230,4 +236,20 @@ class DocumentationViewerTest extends FunctionalTest
// redirect should have been to the absolute url minus the .md extension
$this->assertEquals(Director::absoluteURL('dev/docs/en/doc_test/3.0/tutorials/'), $response->getHeader('Location'));
}
public function testCanonicalUrlIsIncludedInLayout()
{
$response = $this->get('dev/docs/en/doc_test/2.3/subfolder/subsubfolder/subsubpage');
$this->assertEquals(200, $response->getStatusCode());
$expectedUrl = Director::absoluteURL('dev/docs/en/subfolder/subsubfolder/subsubpage/');
$this->assertContains('<link rel="canonical" href="' . $expectedUrl . '" />', (string) $response->getBody());
}
public function testCanonicalUrlIsEmptyWhenNoPageExists()
{
$viewer = new DocumentationViewer;
$this->assertSame('', $viewer->getCanonicalUrl());
}
}

View File

@ -16,20 +16,26 @@ class DocumentationViewerVersionWarningTest extends SapphireTest
Config::nest();
// explicitly use dev/docs. Custom paths should be tested separately
// explicitly use dev/docs. Custom paths should be tested separately
Config::inst()->update(
'DocumentationViewer', 'link_base', 'dev/docs'
'DocumentationViewer',
'link_base',
'dev/docs'
);
// disable automatic module registration so modules don't interfere.
Config::inst()->update(
'DocumentationManifest', 'automatic_registration', false
'DocumentationManifest',
'automatic_registration',
false
);
Config::inst()->remove('DocumentationManifest', 'register_entities');
Config::inst()->update(
'DocumentationManifest', 'register_entities', array(
'DocumentationManifest',
'register_entities',
array(
array(
'Path' => DOCSVIEWER_PATH . "/tests/docs/",
'Title' => 'Doc Test',