mirror of
https://github.com/silverstripe/silverstripe-docsviewer
synced 2024-10-22 11:05:56 +02:00
FEATURE Added parsing support for relative links (relative to module base). Introduced DocumentationPage to encapsulate this information.
ENHANCEMENT Saving $ModuleName in viewer instead of getting it from Remaining[0] MINOR Don't include version in breadcrumbs, doesn't make sense in this context (e.g. "2.4/en/cms", the "2.4" part is connecte to the cms module, hence an index of all versions regardless of module is not very useful)
This commit is contained in:
parent
df4a3ed721
commit
277bca7b11
@ -5,6 +5,9 @@
|
||||
* path with {@link DocumentationService::register()}. This refers to a whole package
|
||||
* rather than a specific page but if we need page options we may need to introduce
|
||||
* a class for that.
|
||||
*
|
||||
* Each folder must have at least one language subfolder, which is automatically
|
||||
* determined through {@link addVersion()} and should not be included in the $path argument.
|
||||
*
|
||||
* @package sapphiredocs
|
||||
*/
|
||||
@ -41,7 +44,7 @@ class DocumentationEntity extends ViewableData {
|
||||
*
|
||||
* @param String $module name of module
|
||||
* @param String $version version of this module
|
||||
* @param String $path path to this module
|
||||
* @param String $path Absolute path to this module (excluding language folders)
|
||||
*/
|
||||
function __construct($module, $version = '', $path, $title = false) {
|
||||
$this->addVersion($version, $path);
|
||||
@ -165,7 +168,7 @@ class DocumentationEntity extends ViewableData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the path to this documentation entity
|
||||
* Return the absolute path to this documentation entity.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
@ -174,9 +177,14 @@ class DocumentationEntity extends ViewableData {
|
||||
if(!$version) $version = '';
|
||||
if(!$lang) $lang = 'en';
|
||||
|
||||
if(!$this->hasVersion($version)) $path = array_pop($this->versions);
|
||||
else $path = $this->versions[$version];
|
||||
// Get version, or fall back to first available
|
||||
if($this->hasVersion($version)) {
|
||||
$path = $this->versions[$version];
|
||||
} else {
|
||||
$versions = $this->getVersions();
|
||||
$path = $this->versions[$versions[0]];
|
||||
}
|
||||
|
||||
return $path . $lang .'/';
|
||||
return $path . '/' . $lang .'/';
|
||||
}
|
||||
}
|
90
code/DocumentationPage.php
Normal file
90
code/DocumentationPage.php
Normal file
@ -0,0 +1,90 @@
|
||||
<?php
|
||||
/**
|
||||
* A specific page within a {@link DocumentationEntity}.
|
||||
* Has to represent an actual file, please use {@link DocumentationViewer}
|
||||
* to generate "virtual" index views.
|
||||
*
|
||||
* @package sapphiredocs
|
||||
*/
|
||||
class DocumentationPage extends ViewableData {
|
||||
|
||||
/**
|
||||
* @var DocumentationEntity
|
||||
*/
|
||||
protected $entity;
|
||||
|
||||
/**
|
||||
* @var String
|
||||
*/
|
||||
protected $relativePath;
|
||||
|
||||
protected $lang = 'en';
|
||||
|
||||
protected $version;
|
||||
|
||||
function __construct($relativePath, $entity, $lang = null, $version = null) {
|
||||
$this->entity = $entity;
|
||||
$this->relativePath = $relativePath;
|
||||
if($lang) $this->lang = $lang;
|
||||
if($version) $this->version = $version;
|
||||
|
||||
if(!file_exists($this->getPath())) {
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'Path could not be found: "%s" (module path: %s, file path: %s)',
|
||||
$this->getPath(),
|
||||
$this->entity->getPath(),
|
||||
$this->relativePath
|
||||
));
|
||||
}
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DocumentationEntity
|
||||
*/
|
||||
function getEntity() {
|
||||
return $this->entity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String Relative path to file or folder within the entity (including file extension),
|
||||
* but excluding version or language folders.
|
||||
*/
|
||||
function getRelativePath() {
|
||||
return $this->relativePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Absolute path including version and lang folder.
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
function getPath() {
|
||||
return realpath($this->entity->getPath($this->version, $this->lang) . '/' . $this->getRelativePath());
|
||||
}
|
||||
|
||||
function getLang() {
|
||||
return $this->lang;
|
||||
}
|
||||
|
||||
function getVersion() {
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return String
|
||||
*/
|
||||
function getMarkdown() {
|
||||
return file_get_contents($this->getPath());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String $baselink
|
||||
* @return String
|
||||
*/
|
||||
function getHTML($baselink = null) {
|
||||
return DocumentationParser::parse($this, $baselink);
|
||||
}
|
||||
|
||||
}
|
@ -8,27 +8,95 @@
|
||||
*/
|
||||
|
||||
class DocumentationParser {
|
||||
|
||||
|
||||
/**
|
||||
* Parse a given path to the documentation for a file. Performs a case insensitive
|
||||
* lookup on the file system. Automatically appends the file extension to one of the markdown
|
||||
* extensions as well so /install/ in a web browser will match /install.md or /INSTALL.md
|
||||
*
|
||||
* @param String $module path to a module
|
||||
* @param Array path of urls. Should be folders, last one is a page
|
||||
*
|
||||
* Filepath: /var/www/myproject/src/cms/en/folder/subfolder/page.md
|
||||
* URL: http://myhost/mywebroot/dev/docs/2.4/cms/en/folder/subfolder/page
|
||||
* Webroot: http://myhost/mywebroot/
|
||||
* Baselink: dev/docs/2.4/cms/en/
|
||||
* Pathparts: folder/subfolder/page
|
||||
*
|
||||
* @param DocumentationPage $page
|
||||
* @param String $baselink Link relative to webroot, up until the "root" of the module.
|
||||
* Necessary to rewrite relative links
|
||||
*
|
||||
* @return HTMLText
|
||||
*/
|
||||
public static function parse($module, $path) {
|
||||
public static function parse(DocumentationPage $page, $baselink = null) {
|
||||
require_once('../sapphiredocs/thirdparty/markdown.php');
|
||||
|
||||
if($content = self::find_page($module, $path)) {
|
||||
$content = Markdown(file_get_contents($content));
|
||||
$md = $page->getMarkdown();
|
||||
|
||||
// Pre-processing
|
||||
$md = self::rewrite_relative_links($md, $page, $baselink);
|
||||
|
||||
$html = Markdown($md);
|
||||
|
||||
return DBField::create('HTMLText', $content);
|
||||
return DBField::create('HTMLText', $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves all relative links within markdown.
|
||||
*
|
||||
* @param String $md Markdown content
|
||||
* @param DocumentationPage $page
|
||||
* @param String $baselink
|
||||
* @return String Markdown
|
||||
*/
|
||||
static function rewrite_relative_links($md, $page, $baselink) {
|
||||
$re = '/
|
||||
\[
|
||||
(.*?) # link title (non greedy)
|
||||
\]
|
||||
\(
|
||||
(.*?) # link url (non greedy)
|
||||
\)
|
||||
/x';
|
||||
preg_match_all($re, $md, $matches);
|
||||
|
||||
// relative path (to module base folder), without the filename
|
||||
$relativePath = dirname($page->getRelativePath());
|
||||
if($relativePath == '.') $relativePath = '';
|
||||
|
||||
if($matches) foreach($matches[0] as $i => $match) {
|
||||
$title = $matches[1][$i];
|
||||
$url = $matches[2][$i];
|
||||
|
||||
// Don't process API links
|
||||
if(preg_match('/^api:/', $url)) continue;
|
||||
|
||||
// Don't process absolute links (based on protocol detection)
|
||||
$urlParts = parse_url($url);
|
||||
if($urlParts && isset($urlParts['scheme'])) continue;
|
||||
|
||||
// Rewrite URL (relative or absolute)
|
||||
if(preg_match('/^\//', $url)) {
|
||||
$relativeUrl = $baselink . $url;
|
||||
} else {
|
||||
$relativeUrl = $baselink . '/' . $relativePath . '/' . $url;
|
||||
}
|
||||
|
||||
// Resolve relative paths
|
||||
while(strpos($relativeUrl, '..') !== FALSE) {
|
||||
$relativeUrl = preg_replace('/\w+\/\.\.\//', '', $relativeUrl);
|
||||
}
|
||||
|
||||
// Replace any double slashes (apart from protocol)
|
||||
$relativeUrl = preg_replace('/([^:])\/{2,}/', '$1/', $relativeUrl);
|
||||
|
||||
// Replace in original content
|
||||
$md = str_replace(
|
||||
$match,
|
||||
sprintf('[%s](%s)', $title, $relativeUrl),
|
||||
$md
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
return $md;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -37,13 +105,13 @@ class DocumentationParser {
|
||||
*
|
||||
* Name may also be a path /install/foo/bar.
|
||||
*
|
||||
* @param String $entity path to the entity
|
||||
* @param String $modulePath Absolute path to the entity
|
||||
* @param Array $path path to the file in the entity
|
||||
*
|
||||
* @return String|false - File path
|
||||
*/
|
||||
private static function find_page($entity, $path) {
|
||||
return self::find_page_recursive($entity, $path);
|
||||
static function find_page($modulePath, $path) {
|
||||
return self::find_page_recursive($modulePath, $path);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -36,8 +36,7 @@ class DocumentationViewer extends Controller {
|
||||
'Lang' => 'Text',
|
||||
'Module' => 'Text',
|
||||
'LanguageTitle' => 'Text'
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
function init() {
|
||||
parent::init();
|
||||
@ -61,9 +60,9 @@ class DocumentationViewer extends Controller {
|
||||
*/
|
||||
public function handleRequest(SS_HTTPRequest $request) {
|
||||
|
||||
$this->Version = $request->shift();
|
||||
$this->Lang = $request->shift();
|
||||
|
||||
$this->Version = $request->shift();
|
||||
$this->Lang = $request->shift();
|
||||
$this->ModuleName = $request->shift();
|
||||
$this->Remaining = $request->shift(10);
|
||||
|
||||
DocumentationService::load_automatic_registration();
|
||||
@ -75,9 +74,11 @@ class DocumentationViewer extends Controller {
|
||||
// /en/sapphire/page which is a link to the latest one
|
||||
|
||||
if(!is_numeric($this->Version)) {
|
||||
array_unshift($this->Remaining, $this->ModuleName);
|
||||
|
||||
// not numeric so /en/sapphire/folder/page
|
||||
if(isset($this->Lang) && $this->Lang)
|
||||
array_unshift($this->Remaining, $this->Lang);
|
||||
$this->ModuleName = $this->Lang;
|
||||
|
||||
$this->Lang = $this->Version;
|
||||
$this->Version = null;
|
||||
@ -108,18 +109,16 @@ class DocumentationViewer extends Controller {
|
||||
// count the number of parameters after the language, version are taken
|
||||
// into account. This automatically includes ' ' so all the counts
|
||||
// are 1 more than what you would expect
|
||||
if($this->Remaining) {
|
||||
if($this->ModuleName || $this->Remaining) {
|
||||
|
||||
$paramCount = count($this->Remaining);
|
||||
|
||||
if($paramCount == 1) {
|
||||
if($paramCount == 0) {
|
||||
return parent::getViewer('folder');
|
||||
}
|
||||
else if($module = $this->getModule()) {
|
||||
$params = $this->Remaining;
|
||||
|
||||
array_shift($params); // module name
|
||||
|
||||
$path = implode('/', array_unique($params));
|
||||
|
||||
if(is_dir($module->getPath() . $path)) return parent::getViewer('folder');
|
||||
@ -224,11 +223,24 @@ class DocumentationViewer extends Controller {
|
||||
|
||||
if($modules) {
|
||||
foreach($modules as $module) {
|
||||
$filepath = $module->getPath() . '/index.md';
|
||||
if(file_exists($filepath)) {
|
||||
$page = new DocumentationPage(
|
||||
$filepath,
|
||||
$module,
|
||||
$this->Lang,
|
||||
$this->Version
|
||||
);
|
||||
$content = DocumentationParser::parse($page, $this->Link(array_slice($this->Remaining, -1, -1)));
|
||||
} else {
|
||||
$content = '';
|
||||
}
|
||||
|
||||
// build the dataset. Load the $Content from an index.md
|
||||
$output->push(new ArrayData(array(
|
||||
'Title' => $module->getTitle(),
|
||||
'Code' => $module,
|
||||
'Content' => DocumentationParser::parse($module->getPath(), array('index'))
|
||||
'Content' => $content
|
||||
)));
|
||||
}
|
||||
}
|
||||
@ -242,13 +254,34 @@ class DocumentationViewer extends Controller {
|
||||
* @return false|DocumentationEntity
|
||||
*/
|
||||
function getModule() {
|
||||
if($this->Remaining && is_array($this->Remaining)) {
|
||||
return DocumentationService::is_registered_module($this->Remaining[0], $this->Version, $this->Lang);
|
||||
if($this->ModuleName) {
|
||||
return DocumentationService::is_registered_module($this->ModuleName, $this->Version, $this->Lang);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return DocumentationPage
|
||||
*/
|
||||
function getPage() {
|
||||
$module = $this->getModule();
|
||||
if(!$module) return false;
|
||||
|
||||
$absFilepath = DocumentationParser::find_page($module->getPath(), $this->Remaining);
|
||||
if($absFilepath) {
|
||||
$relativeFilePath = str_replace($module->getPath(), '', $absFilepath);
|
||||
return new DocumentationPage(
|
||||
$relativeFilePath,
|
||||
$module,
|
||||
$this->Lang,
|
||||
$this->Version
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the related pages to this module and the children to those pages
|
||||
*
|
||||
@ -262,7 +295,7 @@ class DocumentationViewer extends Controller {
|
||||
|
||||
if($pages) {
|
||||
foreach($pages as $page) {
|
||||
$linkParts = array($module->getModuleFolder());
|
||||
$linkParts = array();
|
||||
|
||||
// don't include the 'index in the url
|
||||
if($page->Title != "Index") $linkParts[] = $page->Filename;
|
||||
@ -272,16 +305,14 @@ class DocumentationViewer extends Controller {
|
||||
$page->LinkingMode = 'link';
|
||||
$page->Children = false;
|
||||
|
||||
if(isset($this->Remaining[1])) {
|
||||
if(strtolower($this->Remaining[1]) == $page->Filename) {
|
||||
if(isset($this->Remaining[0])) {
|
||||
if(strtolower($this->Remaining[0]) == $page->Filename) {
|
||||
$page->LinkingMode = 'current';
|
||||
|
||||
if(is_dir($page->Path)) {
|
||||
$children = DocumentationParser::get_pages_from_folder($page->Path);
|
||||
$segments = array($module->getModuleFolder(), $this->Remaining[1]);
|
||||
|
||||
foreach($children as $child) {
|
||||
$child->Link = $this->Link(array_merge($segments, array($child->Filename)));
|
||||
foreach($children as $child) {
|
||||
$child->Link = $this->Link(array($this->Remaining[0], $child->Filename));
|
||||
}
|
||||
|
||||
$page->Children = $children;
|
||||
@ -296,6 +327,7 @@ class DocumentationViewer extends Controller {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the content for the page. If its an actual documentation page then
|
||||
* display the content from the page, otherwise display the contents from
|
||||
@ -304,12 +336,9 @@ class DocumentationViewer extends Controller {
|
||||
* @return HTMLText
|
||||
*/
|
||||
function getContent() {
|
||||
if($module = $this->getModule()) {
|
||||
// name of the module. Throw it away since we already have the module path.
|
||||
$filepath = $this->Remaining;
|
||||
array_shift($filepath);
|
||||
|
||||
return DocumentationParser::parse($module->getPath(), $filepath);
|
||||
if($page = $this->getPage()) {
|
||||
// Remove last portion of path (filename), we want a link to the folder base
|
||||
return DocumentationParser::parse($page, $this->Link(array_slice($this->Remaining, -1, -1)));
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -322,21 +351,23 @@ class DocumentationViewer extends Controller {
|
||||
* @return DataObjectSet
|
||||
*/
|
||||
function getBreadcrumbs() {
|
||||
$pages = $this->Remaining;
|
||||
$pages = array_merge(array($this->ModuleName), $this->Remaining);;
|
||||
|
||||
$output = new DataObjectSet();
|
||||
$output->push(new ArrayData(array(
|
||||
'Title' => ($this->Version) ? $this->Version : _t('DocumentationViewer.DOCUMENTATION', 'Documentation'),
|
||||
'Link' => $this->Link()
|
||||
)));
|
||||
|
||||
// $output->push(new ArrayData(array(
|
||||
// 'Title' => ($this->Version) ? $this->Version : _t('DocumentationViewer.DOCUMENTATION', 'Documentation'),
|
||||
// 'Link' => $this->Link()
|
||||
// )));
|
||||
|
||||
if($pages) {
|
||||
$path = array();
|
||||
|
||||
foreach($pages as $page => $title) {
|
||||
foreach($pages as $i => $title) {
|
||||
if($title) {
|
||||
$path[] = $title;
|
||||
|
||||
// Don't add module name, already present in Link()
|
||||
if($i > 0) $path[] = $title;
|
||||
|
||||
$output->push(new ArrayData(array(
|
||||
'Title' => DocumentationParser::clean_page_name($title),
|
||||
'Link' => $this->Link($path)
|
||||
@ -362,6 +393,7 @@ class DocumentationViewer extends Controller {
|
||||
|
||||
$version = ($this->Version) ? $this->Version . '/' : false;
|
||||
$lang = ($this->Lang) ? $this->Lang .'/' : false;
|
||||
$module = ($this->ModuleName) ? $this->ModuleName .'/' : false;
|
||||
|
||||
$action = '';
|
||||
if(is_string($path)) $action = $path . '/';
|
||||
@ -374,7 +406,7 @@ class DocumentationViewer extends Controller {
|
||||
}
|
||||
}
|
||||
|
||||
return $base . $loc . $version . $lang . $action;
|
||||
return $base . $loc . $version . $lang . $module . $action;
|
||||
}
|
||||
|
||||
/**
|
||||
|
21
tests/DocumentationEntityTest.php
Normal file
21
tests/DocumentationEntityTest.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
/**
|
||||
* @package sapphiredocs
|
||||
*/
|
||||
class DocumentationEntityTest extends SapphireTest {
|
||||
|
||||
function testDocumentationEntityAccessing() {
|
||||
$entity = new DocumentationEntity('docs', '1.0', '../sapphiredocs/tests/docs/', 'My Test');
|
||||
|
||||
$this->assertEquals($entity->getTitle(), 'My Test');
|
||||
$this->assertEquals($entity->getVersions(), array('1.0'));
|
||||
$this->assertEquals($entity->getLanguages(), array('en', 'de'));
|
||||
$this->assertEquals($entity->getModuleFolder(), 'docs');
|
||||
|
||||
$this->assertTrue($entity->hasVersion('1.0'));
|
||||
$this->assertFalse($entity->hasVersion('2.0'));
|
||||
|
||||
$this->assertTrue($entity->hasLanguage('en'));
|
||||
$this->assertFalse($entity->hasLanguage('fr'));
|
||||
}
|
||||
}
|
33
tests/DocumentationPageTest.php
Normal file
33
tests/DocumentationPageTest.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
class DocumentationPageTest extends SapphireTest {
|
||||
|
||||
function testGetRelativePath() {
|
||||
$page = new DocumentationPage(
|
||||
'test.md',
|
||||
new DocumentationEntity('mymodule', null, BASE_PATH . '/sapphiredocs/tests/docs/')
|
||||
);
|
||||
$this->assertEquals('test.md', $page->getRelativePath());
|
||||
|
||||
$page = new DocumentationPage(
|
||||
'subfolder/subpage.md',
|
||||
new DocumentationEntity('mymodule', null, BASE_PATH . '/sapphiredocs/tests/docs/')
|
||||
);
|
||||
$this->assertEquals('subfolder/subpage.md', $page->getRelativePath());
|
||||
}
|
||||
|
||||
function testGetPath() {
|
||||
$absPath = BASE_PATH . '/sapphiredocs/tests/docs/';
|
||||
$page = new DocumentationPage(
|
||||
'test.md',
|
||||
new DocumentationEntity('mymodule', null, $absPath)
|
||||
);
|
||||
$this->assertEquals($absPath . 'en/test.md', $page->getPath());
|
||||
|
||||
$page = new DocumentationPage(
|
||||
'subfolder/subpage.md',
|
||||
new DocumentationEntity('mymodule', null, $absPath)
|
||||
);
|
||||
$this->assertEquals($absPath . 'en/subfolder/subpage.md', $page->getPath());
|
||||
}
|
||||
|
||||
}
|
@ -4,6 +4,109 @@
|
||||
*/
|
||||
class DocumentationParserTest extends SapphireTest {
|
||||
|
||||
function testRelativeLinks() {
|
||||
// Page on toplevel
|
||||
$page = new DocumentationPage(
|
||||
'test.md',
|
||||
new DocumentationEntity('mymodule', null, BASE_PATH . '/sapphiredocs/tests/docs/')
|
||||
);
|
||||
$result = DocumentationParser::rewrite_relative_links($page->getMarkdown(), $page, 'mycontroller/cms/2.4/en/');
|
||||
$this->assertContains(
|
||||
'[link: subfolder index](mycontroller/cms/2.4/en/subfolder/)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: subfolder page](mycontroller/cms/2.4/en/subfolder/subpage)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: http](http://silverstripe.org)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: api](api:DataObject)',
|
||||
$result
|
||||
);
|
||||
|
||||
// Page in subfolder
|
||||
$page = new DocumentationPage(
|
||||
'subfolder/subpage.md',
|
||||
new DocumentationEntity('mymodule', null, BASE_PATH . '/sapphiredocs/tests/docs/')
|
||||
);
|
||||
$result = DocumentationParser::rewrite_relative_links($page->getMarkdown(), $page, 'mycontroller/cms/2.4/en/');
|
||||
$this->assertContains(
|
||||
'[link: absolute index](mycontroller/cms/2.4/en/)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: absolute index with name](mycontroller/cms/2.4/en/index)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: relative index](mycontroller/cms/2.4/en/)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: relative parent page](mycontroller/cms/2.4/en/test)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: absolute parent page](mycontroller/cms/2.4/en/test)',
|
||||
$result
|
||||
);
|
||||
|
||||
// Page in nested subfolder
|
||||
$page = new DocumentationPage(
|
||||
'subfolder/subsubfolder/subsubpage.md',
|
||||
new DocumentationEntity('mymodule', null, BASE_PATH . '/sapphiredocs/tests/docs/')
|
||||
);
|
||||
$result = DocumentationParser::rewrite_relative_links($page->getMarkdown(), $page, 'mycontroller/cms/2.4/en/');
|
||||
$this->assertContains(
|
||||
'[link: absolute index](mycontroller/cms/2.4/en/)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: relative index](mycontroller/cms/2.4/en/subfolder/)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: relative parent page](mycontroller/cms/2.4/en/subfolder/subpage)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: relative grandparent page](mycontroller/cms/2.4/en/test)',
|
||||
$result
|
||||
);
|
||||
$this->assertContains(
|
||||
'[link: absolute page](mycontroller/cms/2.4/en/test)',
|
||||
$result
|
||||
);
|
||||
}
|
||||
|
||||
function testCleanPageNames() {
|
||||
$names = array(
|
||||
'documentation-Page',
|
||||
'documentation_Page',
|
||||
'documentation.md',
|
||||
'documentation.pdf',
|
||||
'documentation.file.txt',
|
||||
'.hidden'
|
||||
);
|
||||
|
||||
$should = array(
|
||||
'Documentation Page',
|
||||
'Documentation Page',
|
||||
'Documentation',
|
||||
'Documentation',
|
||||
'Documentation',
|
||||
'.hidden' // don't display something without a title
|
||||
);
|
||||
|
||||
foreach($names as $key => $value) {
|
||||
$this->assertEquals(DocumentationParser::clean_page_name($value), $should[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
function testGetPagesFromFolder() {
|
||||
$pages = DocumentationParser::get_pages_from_folder(BASE_PATH . '/sapphiredocs/tests/docs/en/');
|
||||
$this->assertContains('index', $pages->column('Filename'), 'Index');
|
||||
|
@ -11,42 +11,131 @@ class DocumentationViewerTests extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'sapphiredocs/tests/DocumentTests.yml';
|
||||
|
||||
function testCleanPageNames() {
|
||||
$names = array(
|
||||
'documentation-Page',
|
||||
'documentation_Page',
|
||||
'documentation.md',
|
||||
'documentation.pdf',
|
||||
'documentation.file.txt',
|
||||
'.hidden'
|
||||
);
|
||||
|
||||
$should = array(
|
||||
'Documentation Page',
|
||||
'Documentation Page',
|
||||
'Documentation',
|
||||
'Documentation',
|
||||
'Documentation',
|
||||
'.hidden' // don't display something without a title
|
||||
);
|
||||
|
||||
foreach($names as $key => $value) {
|
||||
$this->assertEquals(DocumentationParser::clean_page_name($value), $should[$key]);
|
||||
function setUpOnce() {
|
||||
parent::setUpOnce();
|
||||
|
||||
$this->origEnabled = DocumentationService::automatic_registration_enabled();
|
||||
DocumentationService::set_automatic_registration(false);
|
||||
$this->origModules = DocumentationService::get_registered_modules();
|
||||
foreach($this->origModules as $module) {
|
||||
DocumentationService::unregister($module->getModuleFolder());
|
||||
}
|
||||
DocumentationService::register("DocumentationViewerTests", BASE_PATH . "/sapphiredocs/tests/docs/", '2.4');
|
||||
}
|
||||
|
||||
function testDocumentationEntityAccessing() {
|
||||
$entity = new DocumentationEntity('docs', '1.0', '../sapphiredocs/tests/docs/', 'My Test');
|
||||
function tearDownOnce() {
|
||||
parent::tearDownOnce();
|
||||
|
||||
$this->assertEquals($entity->getTitle(), 'My Test');
|
||||
$this->assertEquals($entity->getVersions(), array('1.0'));
|
||||
$this->assertEquals($entity->getLanguages(), array('en', 'de'));
|
||||
$this->assertEquals($entity->getModuleFolder(), 'docs');
|
||||
|
||||
$this->assertTrue($entity->hasVersion('1.0'));
|
||||
$this->assertFalse($entity->hasVersion('2.0'));
|
||||
|
||||
$this->assertTrue($entity->hasLanguage('en'));
|
||||
$this->assertFalse($entity->hasLanguage('fr'));
|
||||
DocumentationService::unregister("DocumentationViewerTests");
|
||||
DocumentationService::set_automatic_registration($this->origEnabled);
|
||||
// $this->origModules = Documentation::get_registered_modules();
|
||||
// foreach($this->origModules as $name => $module) {
|
||||
// DocumentationService::register($name);
|
||||
// }
|
||||
}
|
||||
|
||||
function testUrlParsing() {
|
||||
// Module index
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/test'));
|
||||
$this->assertEquals('2.4', $v->Version);
|
||||
$this->assertEquals('en', $v->Lang);
|
||||
$this->assertEquals('DocumentationViewerTests', $v->ModuleName);
|
||||
$this->assertEquals(array('test'), $v->Remaining);
|
||||
|
||||
// Module index without version and language
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', 'en/DocumentationViewerTests/test'));
|
||||
$this->assertEquals(null, $v->Version);
|
||||
$this->assertEquals('en', $v->Lang);
|
||||
$this->assertEquals('DocumentationViewerTests', $v->ModuleName);
|
||||
$this->assertEquals(array('test'), $v->Remaining);
|
||||
|
||||
// Overall index
|
||||
// $v = new DocumentationViewer();
|
||||
// $response = $v->handleRequest(new SS_HTTPRequest('GET', ''));
|
||||
// $this->assertEquals(null, $v->Version);
|
||||
// $this->assertEquals(null, $v->Lang);
|
||||
// $this->assertEquals(null, $v->ModuleName);
|
||||
// $this->assertEquals(array(), $v->Remaining);
|
||||
}
|
||||
|
||||
function testBreadcrumbs() {
|
||||
// Module index
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/'));
|
||||
$crumbs = $v->getBreadcrumbs();
|
||||
$this->assertEquals(1, $crumbs->Count());
|
||||
$crumbLinks = $crumbs->column('Link');
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/', $crumbLinks[0]);
|
||||
|
||||
// Subfolder index
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/subfolder/'));
|
||||
$crumbs = $v->getBreadcrumbs();
|
||||
$this->assertEquals(2, $crumbs->Count());
|
||||
$crumbLinks = $crumbs->column('Link');
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/', $crumbLinks[0]);
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/subfolder/', $crumbLinks[1]);
|
||||
|
||||
// Subfolder page
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/subfolder/subpage'));
|
||||
$crumbs = $v->getBreadcrumbs();
|
||||
$this->assertEquals(3, $crumbs->Count());
|
||||
$crumbLinks = $crumbs->column('Link');
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/', $crumbLinks[0]);
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/subfolder/', $crumbLinks[1]);
|
||||
$this->assertStringEndsWith('DocumentationViewerTests/subfolder/subpage/', $crumbLinks[2]);
|
||||
}
|
||||
|
||||
function testGetModulePages() {
|
||||
$v = new DocumentationViewer();
|
||||
$response = $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/DocumentationViewerTests/subfolder/'));
|
||||
$pages = $v->getModulePages();
|
||||
$this->assertEquals(
|
||||
array('index', 'subfolder', 'test'),
|
||||
$pages->column('Filename')
|
||||
);
|
||||
$this->assertEquals(
|
||||
array('link', 'current', 'link'),
|
||||
$pages->column('LinkingMode')
|
||||
);
|
||||
$links = $pages->column('Link');
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/', $links[0]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/', $links[1]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/test/', $links[2]);
|
||||
|
||||
// Children
|
||||
$pagesArr = $pages->toArray();
|
||||
$child1 = $pagesArr[0];
|
||||
$this->assertFalse($child1->Children);
|
||||
|
||||
$child2 = $pagesArr[1];
|
||||
$this->assertType('DataObjectSet', $child2->Children);
|
||||
$this->assertEquals(
|
||||
array('subpage', 'subsubfolder'),
|
||||
$child2->Children->column('Filename')
|
||||
);
|
||||
$child2Links = $child2->Children->column('Link');
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/subpage/', $child2Links[0]);
|
||||
$this->assertStringEndsWith('2.4/en/DocumentationViewerTests/subfolder/subsubfolder/', $child2Links[1]);
|
||||
}
|
||||
|
||||
function testRouting() {
|
||||
$response = $this->get('dev/docs/2.4/en/DocumentationViewerTests/test');
|
||||
$this->assertEquals(200, $response->getStatusCode());
|
||||
$this->assertContains('english test', $response->getBody(), 'Toplevel content page');
|
||||
}
|
||||
|
||||
// function testGetPage() {
|
||||
// $v = new DocumentationViewer();
|
||||
// $v->handleRequest(new SS_HTTPRequest('GET', '2.4/en/cms'));
|
||||
// $p = $v->getPage();
|
||||
// $this->assertType('DocumentationPage', $p);
|
||||
// $this->assertEquals('/', $p->getRelativePath());
|
||||
// $this->assertEquals('en', $p->getLang());
|
||||
// $this->assertEquals('2.4', $p->getVersion());
|
||||
// }
|
||||
|
||||
}
|
5
tests/docs/en/subfolder/subpage.md
Normal file
5
tests/docs/en/subfolder/subpage.md
Normal file
@ -0,0 +1,5 @@
|
||||
[link: absolute index](/)
|
||||
[link: absolute index with name](/index)
|
||||
[link: relative index](../)
|
||||
[link: relative parent page](../test)
|
||||
[link: absolute parent page](/test)
|
5
tests/docs/en/subfolder/subsubfolder/subsubpage.md
Normal file
5
tests/docs/en/subfolder/subsubfolder/subsubpage.md
Normal file
@ -0,0 +1,5 @@
|
||||
[link: absolute index](/)
|
||||
[link: relative index](../)
|
||||
[link: relative parent page](../subpage)
|
||||
[link: relative grandparent page](../../test)
|
||||
[link: absolute page](/test)
|
@ -2,4 +2,10 @@
|
||||
|
||||
test
|
||||
|
||||
1.0
|
||||
1.0
|
||||
|
||||
[link: subfolder index](subfolder/)
|
||||
[link: subfolder page](subfolder/subpage)
|
||||
[link: with anchor](/test#anchor)
|
||||
[link: http](http://silverstripe.org)
|
||||
[link: api](api:DataObject)
|
Loading…
Reference in New Issue
Block a user