Merge pull request #55 from camfindlay/branchalias

ENHANCEMENT optional branch property to allow version aliases.
This commit is contained in:
Will Rossiter 2015-01-07 14:10:50 +13:00
commit 9a2deea414
4 changed files with 151 additions and 103 deletions

View File

@ -3,7 +3,7 @@
/** /**
* A class which builds a manifest of all documentation present in a project. * A class which builds a manifest of all documentation present in a project.
* *
* The manifest is required to map the provided documentation URL rules to a * The manifest is required to map the provided documentation URL rules to a
* file path on the server. The stored cache looks similar to the following: * file path on the server. The stored cache looks similar to the following:
* *
* <code> * <code>
@ -92,7 +92,7 @@ class DocumentationManifest {
/** /**
* Sets up the top level entities. * Sets up the top level entities.
* *
* Either manually registered through the YAML syntax or automatically * Either manually registered through the YAML syntax or automatically
* loaded through investigating the file system for `docs` folder. * loaded through investigating the file system for `docs` folder.
*/ */
public function setupEntities() { public function setupEntities() {
@ -128,11 +128,13 @@ class DocumentationManifest {
$version = (isset($details['Version'])) ? $details['Version'] : ''; $version = (isset($details['Version'])) ? $details['Version'] : '';
$branch = (isset($details['Branch'])) ? $details['Branch'] : '';
$langs = scandir($path); $langs = scandir($path);
if($langs) { if($langs) {
$possible = i18n::get_common_languages(true); $possible = i18n::get_common_languages(true);
foreach($langs as $k => $lang) { foreach($langs as $k => $lang) {
if(isset($possible[$lang])) { if(isset($possible[$lang])) {
$entity = Injector::inst()->create( $entity = Injector::inst()->create(
@ -143,6 +145,7 @@ class DocumentationManifest {
$entity->setTitle($details['Title']); $entity->setTitle($details['Title']);
$entity->setLanguage($lang); $entity->setLanguage($lang);
$entity->setVersion($version); $entity->setVersion($version);
$entity->setBranch($branch);
if(isset($details['Stable'])) { if(isset($details['Stable'])) {
$entity->setIsStable($details['Stable']); $entity->setIsStable($details['Stable']);
@ -192,7 +195,7 @@ class DocumentationManifest {
} }
$dir = Controller::join_links(BASE_PATH, $entity); $dir = Controller::join_links(BASE_PATH, $entity);
if(is_dir($dir)) { if(is_dir($dir)) {
// check to see if it has docs // check to see if it has docs
$docs = Controller::join_links($dir, 'docs'); $docs = Controller::join_links($dir, 'docs');
@ -202,6 +205,7 @@ class DocumentationManifest {
'Path' => $docs, 'Path' => $docs,
'Title' => DocumentationHelper::clean_page_name($entity), 'Title' => DocumentationHelper::clean_page_name($entity),
'Version' => 'master', 'Version' => 'master',
'Branch' => 'master',
'Stable' => true 'Stable' => true
); );
} }
@ -242,7 +246,7 @@ class DocumentationManifest {
} }
/** /**
* Returns a particular page for the requested URL. * Returns a particular page for the requested URL.
* *
* @return DocumentationPage * @return DocumentationPage
*/ */
@ -260,7 +264,7 @@ class DocumentationManifest {
foreach($this->getEntities() as $entity) { foreach($this->getEntities() as $entity) {
if(strpos($record['filepath'], $entity->getPath()) !== false) { if(strpos($record['filepath'], $entity->getPath()) !== false) {
$page = Injector::inst()->create( $page = Injector::inst()->create(
$record['type'], $record['type'],
$entity, $entity,
$record['basename'], $record['basename'],
$record['filepath'] $record['filepath']
@ -285,11 +289,11 @@ class DocumentationManifest {
foreach($this->getEntities() as $entity) { foreach($this->getEntities() as $entity) {
$this->entity = $entity; $this->entity = $entity;
$this->handleFolder('', $this->entity->getPath(), 0); $this->handleFolder('', $this->entity->getPath(), 0);
$finder->find($this->entity->getPath()); $finder->find($this->entity->getPath());
} }
// groupds // groupds
$grouped = array(); $grouped = array();
@ -316,7 +320,7 @@ class DocumentationManifest {
if ($a['filepath'] == $b['filepath']) { if ($a['filepath'] == $b['filepath']) {
return 0; return 0;
} }
return ($a['filepath'] < $b['filepath']) ? -1 : 1; return ($a['filepath'] < $b['filepath']) ? -1 : 1;
}); });
@ -339,8 +343,8 @@ class DocumentationManifest {
); );
$link = ltrim(str_replace( $link = ltrim(str_replace(
Config::inst()->get('DocumentationViewer', 'link_base'), Config::inst()->get('DocumentationViewer', 'link_base'),
'', '',
$folder->Link() $folder->Link()
), '/'); ), '/');
@ -355,9 +359,9 @@ class DocumentationManifest {
} }
/** /**
* Individual files can optionally provide a nice title and a better URL * Individual files can optionally provide a nice title and a better URL
* through the use of markdown meta data. This creates a new * through the use of markdown meta data. This creates a new
* {@link DocumentationPage} instance for the file. * {@link DocumentationPage} instance for the file.
* *
* If the markdown does not specify the title in the meta data it falls back * If the markdown does not specify the title in the meta data it falls back
* to using the file name. * to using the file name.
@ -368,7 +372,7 @@ class DocumentationManifest {
*/ */
public function handleFile($basename, $path, $depth) { public function handleFile($basename, $path, $depth) {
$page = Injector::inst()->create( $page = Injector::inst()->create(
'DocumentationPage', 'DocumentationPage',
$this->entity, $basename, $path $this->entity, $basename, $path
); );
@ -376,11 +380,11 @@ class DocumentationManifest {
$page->getMarkdown(); $page->getMarkdown();
$link = ltrim(str_replace( $link = ltrim(str_replace(
Config::inst()->get('DocumentationViewer', 'link_base'), Config::inst()->get('DocumentationViewer', 'link_base'),
'', '',
$page->Link() $page->Link()
), '/'); ), '/');
$this->pages[$link] = array( $this->pages[$link] = array(
'title' => $page->getTitle(), 'title' => $page->getTitle(),
'filepath' => $path, 'filepath' => $path,
@ -403,7 +407,7 @@ class DocumentationManifest {
$output = new ArrayList(); $output = new ArrayList();
$parts = explode('/', trim($record->getRelativeLink(), '/')); $parts = explode('/', trim($record->getRelativeLink(), '/'));
// Add the base link. // Add the base link.
$output->push(new ArrayData(array( $output->push(new ArrayData(array(
'Link' => $base->Link(), 'Link' => $base->Link(),
@ -429,7 +433,7 @@ class DocumentationManifest {
/** /**
* Determine the next page from the given page. * Determine the next page from the given page.
* *
* Relies on the fact when the manifest was built, it was generated in * Relies on the fact when the manifest was built, it was generated in
* order. * order.
* *
* @param string $filepath * @param string $filepath
@ -470,7 +474,7 @@ class DocumentationManifest {
/** /**
* Determine the previous page from the given page. * Determine the previous page from the given page.
* *
* Relies on the fact when the manifest was built, it was generated in * Relies on the fact when the manifest was built, it was generated in
* order. * order.
* *
* @param string $filepath * @param string $filepath
@ -508,7 +512,7 @@ class DocumentationManifest {
public function normalizeUrl($url) { public function normalizeUrl($url) {
$url = trim($url, '/') .'/'; $url = trim($url, '/') .'/';
// if the page is the index page then hide it from the menu // if the page is the index page then hide it from the menu
if(strpos(strtolower($url), '/index.md/')) { if(strpos(strtolower($url), '/index.md/')) {
$url = substr($url, 0, strpos($url, "index.md/")); $url = substr($url, 0, strpos($url, "index.md/"));
} }
@ -529,12 +533,12 @@ class DocumentationManifest {
if(!$recordPath) { if(!$recordPath) {
$recordPath = $entityPath; $recordPath = $entityPath;
} }
$output = new ArrayList(); $output = new ArrayList();
$base = Config::inst()->get('DocumentationViewer', 'link_base'); $base = Config::inst()->get('DocumentationViewer', 'link_base');
$entityPath = $this->normalizeUrl($entityPath); $entityPath = $this->normalizeUrl($entityPath);
$recordPath = $this->normalizeUrl($recordPath); $recordPath = $this->normalizeUrl($recordPath);
$recordParts = explode(DIRECTORY_SEPARATOR, trim($recordPath,'/')); $recordParts = explode(DIRECTORY_SEPARATOR, trim($recordPath,'/'));
$currentRecordPath = end($recordParts); $currentRecordPath = end($recordParts);
$depth = substr_count($entityPath, '/'); $depth = substr_count($entityPath, '/');
@ -548,18 +552,18 @@ class DocumentationManifest {
// only pull it up if it's one more level depth // only pull it up if it's one more level depth
if(substr_count($pagePath, DIRECTORY_SEPARATOR) == ($depth + 1)) { if(substr_count($pagePath, DIRECTORY_SEPARATOR) == ($depth + 1)) {
$pagePathParts = explode(DIRECTORY_SEPARATOR, trim($pagePath,'/')); $pagePathParts = explode(DIRECTORY_SEPARATOR, trim($pagePath,'/'));
$currentPagePath = end($pagePathParts); $currentPagePath = end($pagePathParts);
if($currentPagePath == $currentRecordPath) { if($currentPagePath == $currentRecordPath) {
$mode = 'current'; $mode = 'current';
} }
else if(strpos($recordPath, $pagePath) !== false) { else if(strpos($recordPath, $pagePath) !== false) {
$mode = 'section'; $mode = 'section';
} }
else { else {
$mode = 'link'; $mode = 'link';
} }
$children = new ArrayList(); $children = new ArrayList();
if($mode == 'section' || $mode == 'current') { if($mode == 'section' || $mode == 'current') {
@ -583,7 +587,7 @@ class DocumentationManifest {
* @param DocumentationEntity * @param DocumentationEntity
* *
* @return ArrayList * @return ArrayList
*/ */
public function getAllVersionsOfEntity(DocumentationEntity $entity) { public function getAllVersionsOfEntity(DocumentationEntity $entity) {
$all = new ArrayList(); $all = new ArrayList();
@ -602,7 +606,7 @@ class DocumentationManifest {
* @param DocumentationEntity * @param DocumentationEntity
* *
* @return DocumentationEntity * @return DocumentationEntity
*/ */
public function getStableVersion(DocumentationEntity $entity) { public function getStableVersion(DocumentationEntity $entity) {
foreach($this->getEntities() as $check) { foreach($this->getEntities() as $check) {
if($check->getKey() == $entity->getKey()) { if($check->getKey() == $entity->getKey()) {
@ -621,19 +625,19 @@ class DocumentationManifest {
* @param DocumentationEntity * @param DocumentationEntity
* *
* @return ArrayList * @return ArrayList
*/ */
public function getVersions($entity) { public function getVersions($entity) {
if(!$entity) { if(!$entity) {
return null; return null;
} }
$output = new ArrayList(); $output = new ArrayList();
foreach($this->getEntities() as $check) { foreach($this->getEntities() as $check) {
if($check->getKey() == $entity->getKey()) { if($check->getKey() == $entity->getKey()) {
if($check->getLanguage() == $entity->getLanguage()) { if($check->getLanguage() == $entity->getLanguage()) {
$same = ($check->getVersion() == $entity->getVersion()); $same = ($check->getVersion() == $entity->getVersion());
$output->push(new ArrayData(array( $output->push(new ArrayData(array(
'Title' => $check->getVersion(), 'Title' => $check->getVersion(),
'Link' => $check->Link(), 'Link' => $check->Link(),
@ -652,7 +656,7 @@ class DocumentationManifest {
*/ */
public function getAllVersions() { public function getAllVersions() {
$versions = array(); $versions = array();
foreach($this->getEntities() as $entity) { foreach($this->getEntities() as $entity) {
if($entity->getVersion()) { if($entity->getVersion()) {
$versions[$entity->getVersion()] = $entity->getVersion(); $versions[$entity->getVersion()] = $entity->getVersion();
@ -660,9 +664,9 @@ class DocumentationManifest {
$versions['0.0'] = _t('DocumentationManifest.MASTER', 'Master'); $versions['0.0'] = _t('DocumentationManifest.MASTER', 'Master');
} }
} }
asort($versions); asort($versions);
return $versions; return $versions;
} }
} }

View File

@ -3,7 +3,7 @@
/** /**
* Documentation Viewer. * Documentation Viewer.
* *
* Reads the bundled markdown files from documentation folders and displays the * Reads the bundled markdown files from documentation folders and displays the
* output (either via markdown or plain text). * output (either via markdown or plain text).
* *
* For more documentation on how to use this class see the documentation in the * For more documentation on how to use this class see the documentation in the
@ -31,7 +31,7 @@ class DocumentationViewer extends Controller {
* @var string * @var string
*/ */
private static $documentation_title = 'SilverStripe Documentation'; private static $documentation_title = 'SilverStripe Documentation';
/** /**
* @var array * @var array
*/ */
@ -65,7 +65,7 @@ class DocumentationViewer extends Controller {
* @var string same as the routing pattern set through Director::addRules(). * @var string same as the routing pattern set through Director::addRules().
*/ */
private static $link_base = 'dev/docs/'; private static $link_base = 'dev/docs/';
/** /**
* @config * @config
* *
@ -91,9 +91,9 @@ class DocumentationViewer extends Controller {
Requirements::javascript('//use.typekit.net/emt4dhq.js'); Requirements::javascript('//use.typekit.net/emt4dhq.js');
Requirements::customScript('try{Typekit.load();}catch(e){}'); Requirements::customScript('try{Typekit.load();}catch(e){}');
Requirements::javascript(THIRDPARTY_DIR .'/jquery/jquery.js'); Requirements::javascript(THIRDPARTY_DIR .'/jquery/jquery.js');
Requirements::javascript('https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js'); Requirements::javascript('https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js');
Requirements::javascript(DOCSVIEWER_DIR .'/javascript/DocumentationViewer.js'); Requirements::javascript(DOCSVIEWER_DIR .'/javascript/DocumentationViewer.js');
Requirements::combine_files('docs.css', array( Requirements::combine_files('docs.css', array(
DOCSVIEWER_DIR .'/css/normalize.css', DOCSVIEWER_DIR .'/css/normalize.css',
@ -104,16 +104,16 @@ class DocumentationViewer extends Controller {
DOCSVIEWER_DIR .'/css/small.css' DOCSVIEWER_DIR .'/css/small.css'
)); ));
} }
/** /**
* Can the user view this documentation. Hides all functionality for private * Can the user view this documentation. Hides all functionality for private
* wikis. * wikis.
* *
* @return bool * @return bool
*/ */
public function canView() { public function canView() {
return (Director::isDev() || Director::is_cli() || return (Director::isDev() || Director::is_cli() ||
!$this->config()->get('check_permission') || !$this->config()->get('check_permission') ||
Permission::check($this->config()->get('check_permission')) Permission::check($this->config()->get('check_permission'))
); );
} }
@ -127,8 +127,8 @@ class DocumentationViewer extends Controller {
} }
/** /**
* Overloaded to avoid "action doesn't exist" errors - all URL parts in * Overloaded to avoid "action doesn't exist" errors - all URL parts in
* this controller are virtual and handled through handleRequest(), not * this controller are virtual and handled through handleRequest(), not
* controller methods. * controller methods.
* *
* @param $request * @param $request
@ -145,20 +145,20 @@ class DocumentationViewer extends Controller {
$url = $request->getURL(); $url = $request->getURL();
// //
// If the current request has an extension attached to it, strip that // If the current request has an extension attached to it, strip that
// off and redirect the user to the page without an extension. // off and redirect the user to the page without an extension.
// //
if(DocumentationHelper::get_extension($url)) { if(DocumentationHelper::get_extension($url)) {
$this->response = new SS_HTTPResponse(); $this->response = new SS_HTTPResponse();
$this->response->redirect( $this->response->redirect(
DocumentationHelper::trim_extension_off($url) .'/', DocumentationHelper::trim_extension_off($url) .'/',
301 301
); );
$request->shift(); $request->shift();
$request->shift(); $request->shift();
return $this->response; return $this->response;
} }
// //
@ -170,22 +170,22 @@ class DocumentationViewer extends Controller {
if($base && strpos($url, $base) !== false) { if($base && strpos($url, $base) !== false) {
$url = substr( $url = substr(
ltrim($url, '/'), ltrim($url, '/'),
strlen($base) strlen($base)
); );
} else { } else {
} }
// //
// Handle any permanent redirections that the developer has defined. // Handle any permanent redirections that the developer has defined.
// //
if($link = DocumentationPermalinks::map($url)) { if($link = DocumentationPermalinks::map($url)) {
// the first param is a shortcode for a page so redirect the user to // the first param is a shortcode for a page so redirect the user to
// the short code. // the short code.
$this->response = new SS_HTTPResponse(); $this->response = new SS_HTTPResponse();
$this->response->redirect($link, 301); $this->response->redirect($link, 301);
$request->shift(); $request->shift();
$request->shift(); $request->shift();
@ -194,7 +194,7 @@ class DocumentationViewer extends Controller {
// //
// Validate the language provided. Language is a required URL parameter. // Validate the language provided. Language is a required URL parameter.
// as we use it for generic interfaces and language selection. If // as we use it for generic interfaces and language selection. If
// language is not set, redirects to 'en' // language is not set, redirects to 'en'
// //
$languages = i18n::get_common_languages(); $languages = i18n::get_common_languages();
@ -245,7 +245,7 @@ class DocumentationViewer extends Controller {
"DocumentationViewer_{$type}", "DocumentationViewer_{$type}",
"DocumentationViewer" "DocumentationViewer"
)); ));
return new SS_HTTPResponse($body, 200); return new SS_HTTPResponse($body, 200);
} else if(!$url || $url == $lang) { } else if(!$url || $url == $lang) {
$body = $this->renderWith(array( $body = $this->renderWith(array(
@ -268,7 +268,7 @@ class DocumentationViewer extends Controller {
*/ */
public function httpError($status, $message = null) { public function httpError($status, $message = null) {
$this->init(); $this->init();
$class = get_class($this); $class = get_class($this);
$body = $this->customise(new ArrayData(array( $body = $this->customise(new ArrayData(array(
'Message' => $message 'Message' => $message
@ -283,7 +283,7 @@ class DocumentationViewer extends Controller {
public function getManifest() { public function getManifest() {
if(!$this->manifest) { if(!$this->manifest) {
$flush = SapphireTest::is_running_test() || (isset($_GET['flush'])); $flush = SapphireTest::is_running_test() || (isset($_GET['flush']));
$this->manifest = new DocumentationManifest($flush); $this->manifest = new DocumentationManifest($flush);
} }
@ -304,11 +304,11 @@ class DocumentationViewer extends Controller {
/** /**
* Generate a list of {@link Documentation } which have been registered and which can * Generate a list of {@link Documentation } which have been registered and which can
* be documented. * be documented.
* *
* @return DataObject * @return DataObject
*/ */
public function getMenu() { public function getMenu() {
$entities = $this->getManifest()->getEntities(); $entities = $this->getManifest()->getEntities();
$output = new ArrayList(); $output = new ArrayList();
@ -319,25 +319,25 @@ class DocumentationViewer extends Controller {
$checkLang = $entity->getLanguage(); $checkLang = $entity->getLanguage();
$checkVers = $entity->getVersion(); $checkVers = $entity->getVersion();
// only show entities with the same language or any entity that // only show entities with the same language or any entity that
// isn't registered under any particular language (auto detected) // isn't registered under any particular language (auto detected)
if($checkLang && $checkLang !== $this->getLanguage()) { if($checkLang && $checkLang !== $this->getLanguage()) {
continue; continue;
} }
if($current && $checkVers) { if($current && $checkVers) {
if($entity->getVersion() !== $current->getVersion()) { if($entity->getVersion() !== $current->getVersion()) {
continue; continue;
} }
} }
$mode = 'link'; $mode = 'link';
$children = new ArrayList(); $children = new ArrayList();
if($entity->hasRecord($record) || $entity->getIsDefaultEntity()) { if($entity->hasRecord($record) || $entity->getIsDefaultEntity()) {
$mode = 'current'; $mode = 'current';
// add children // add children
$children = $this->getManifest()->getChildrenFor( $children = $this->getManifest()->getChildrenFor(
$entity->getPath(), ($record) ? $record->getPath() : $entity->getPath() $entity->getPath(), ($record) ? $record->getPath() : $entity->getPath()
); );
@ -360,7 +360,7 @@ class DocumentationViewer extends Controller {
return $output; return $output;
} }
/** /**
* Return the content for the page. If its an actual documentation page then * Return the content for the page. If its an actual documentation page then
* display the content from the page, otherwise display the contents from * display the content from the page, otherwise display the contents from
@ -430,7 +430,7 @@ class DocumentationViewer extends Controller {
return new ArrayList(); return new ArrayList();
} }
/** /**
* Generate a list of breadcrumbs for the user. * Generate a list of breadcrumbs for the user.
* *
@ -474,7 +474,7 @@ class DocumentationViewer extends Controller {
public function getTitle() { public function getTitle() {
return ($this->record) ? $this->record->getTitle() : null; return ($this->record) ? $this->record->getTitle() : null;
} }
/** /**
* @return string * @return string
*/ */
@ -502,7 +502,7 @@ class DocumentationViewer extends Controller {
} }
/** /**
* Generate a list of all the pages in the documentation grouped by the * Generate a list of all the pages in the documentation grouped by the
* first letter of the page. * first letter of the page.
* *
* @return GroupedList * @return GroupedList
@ -525,7 +525,7 @@ class DocumentationViewer extends Controller {
return GroupedList::create($output->sort('Title', 'ASC')); return GroupedList::create($output->sort('Title', 'ASC'));
} }
/** /**
* Documentation Search Form. Allows filtering of the results by many entities * Documentation Search Form. Allows filtering of the results by many entities
* and multiple versions. * and multiple versions.
@ -536,13 +536,13 @@ class DocumentationViewer extends Controller {
if(!Config::inst()->get('DocumentationSearch','enabled')) { if(!Config::inst()->get('DocumentationSearch','enabled')) {
return false; return false;
} }
return new DocumentationSearchForm($this); return new DocumentationSearchForm($this);
} }
/** /**
* Sets the mapping between a entity name and the link for the end user * Sets the mapping between a entity name and the link for the end user
* to jump into editing the documentation. * to jump into editing the documentation.
* *
* Some variables are replaced: * Some variables are replaced:
* - %version% * - %version%
@ -554,7 +554,7 @@ class DocumentationViewer extends Controller {
* *
* <code> * <code>
* DocumentationViewer::set_edit_link( * DocumentationViewer::set_edit_link(
* 'framework', * 'framework',
* 'https://github.com/silverstripe/%entity%/edit/%version%/docs/%lang%/%path%', * 'https://github.com/silverstripe/%entity%/edit/%version%/docs/%lang%/%path%',
* $opts * $opts
* )); * ));
@ -592,6 +592,11 @@ class DocumentationViewer extends Controller {
$url = self::$edit_links[strtolower($entity->title)]; $url = self::$edit_links[strtolower($entity->title)];
$version = $entity->getVersion(); $version = $entity->getVersion();
if($entity->getBranch()){
$version = $entity->getBranch();
}
if($version == "trunk" && (isset($url['options']['rewritetrunktomaster']))) { if($version == "trunk" && (isset($url['options']['rewritetrunktomaster']))) {
if($url['options']['rewritetrunktomaster']) { if($url['options']['rewritetrunktomaster']) {
$version = "master"; $version = "master";
@ -601,9 +606,9 @@ class DocumentationViewer extends Controller {
return str_replace( return str_replace(
array('%entity%', '%lang%', '%version%', '%path%'), array('%entity%', '%lang%', '%version%', '%path%'),
array( array(
$entity->title, $entity->title,
$this->getLanguage(), $this->getLanguage(),
$version, $version,
ltrim($page->getRelativePath(), '/') ltrim($page->getRelativePath(), '/')
), ),
@ -624,25 +629,25 @@ class DocumentationViewer extends Controller {
* @return DocumentationPage * @return DocumentationPage
*/ */
public function getNextPage() { public function getNextPage() {
return ($this->record) return ($this->record)
? $this->getManifest()->getNextPage( ? $this->getManifest()->getNextPage(
$this->record->getPath(), $this->getEntity()->getPath()) $this->record->getPath(), $this->getEntity()->getPath())
: null; : null;
} }
/** /**
* Returns the previous page. Either returns the previous sibling or the * Returns the previous page. Either returns the previous sibling or the
* parent of this page * parent of this page
* *
* @return DocumentationPage * @return DocumentationPage
*/ */
public function getPreviousPage() { public function getPreviousPage() {
return ($this->record) return ($this->record)
? $this->getManifest()->getPreviousPage( ? $this->getManifest()->getPreviousPage(
$this->record->getPath(), $this->getEntity()->getPath()) $this->record->getPath(), $this->getEntity()->getPath())
: null; : null;
} }
/** /**
* @return string * @return string
*/ */

View File

@ -2,25 +2,25 @@
/** /**
* A {@link DocumentationEntity} represents a module or folder with stored * A {@link DocumentationEntity} represents a module or folder with stored
* documentation files. An entity not an individual page but a `section` of * documentation files. An entity not an individual page but a `section` of
* documentation arranged by version and language. * documentation arranged by version and language.
* *
* Each entity has a version assigned to it (i.e master) and folders can be * Each entity has a version assigned to it (i.e master) and folders can be
* labeled with a specific version. For instance, doc.silverstripe.org has three * labeled with a specific version. For instance, doc.silverstripe.org has three
* DocumentEntities for Framework - versions 2.4, 3.0 and 3.1. In addition an * DocumentEntities for Framework - versions 2.4, 3.0 and 3.1. In addition an
* entity can have a language attached to it. So for an instance with en, de and * entity can have a language attached to it. So for an instance with en, de and
* fr documentation you may have three {@link DocumentationEntities} registered. * fr documentation you may have three {@link DocumentationEntities} registered.
* *
* *
* @package docsviewer * @package docsviewer
* @subpackage models * @subpackage models
*/ */
class DocumentationEntity extends ViewableData { class DocumentationEntity extends ViewableData {
/** /**
* The key to match entities with that is not localized. For instance, you * The key to match entities with that is not localized. For instance, you
* may have three entities (en, de, fr) that you want to display a nice * may have three entities (en, de, fr) that you want to display a nice
* title for, but matching needs to occur on a specific key. * title for, but matching needs to occur on a specific key.
* *
* @var string $key * @var string $key
@ -28,7 +28,7 @@ class DocumentationEntity extends ViewableData {
protected $key; protected $key;
/** /**
* The human readable title of this entity. Set when the module is * The human readable title of this entity. Set when the module is
* registered. * registered.
* *
* @var string $title * @var string $title
@ -36,7 +36,7 @@ class DocumentationEntity extends ViewableData {
protected $title; protected $title;
/** /**
* If the system is setup to only document one entity then you may only * If the system is setup to only document one entity then you may only
* want to show a single entity in the URL and the sidebar. Set this when * want to show a single entity in the URL and the sidebar. Set this when
* you register the entity with the key `DefaultEntity` and the URL will * you register the entity with the key `DefaultEntity` and the URL will
* not include any version or language information. * not include any version or language information.
@ -57,7 +57,14 @@ class DocumentationEntity extends ViewableData {
protected $version; protected $version;
/** /**
* If this entity is a stable release or not. If it is not stable (i.e it * The repository branch name (allows for $version to be an alias on development branches).
*
* @var string $branch
*/
protected $branch;
/**
* If this entity is a stable release or not. If it is not stable (i.e it
* could be a past or future release) then a warning message will be shown. * could be a past or future release) then a warning message will be shown.
* *
* @var boolean $stable * @var boolean $stable
@ -70,12 +77,12 @@ class DocumentationEntity extends ViewableData {
protected $language; protected $language;
/** /**
* *
*/ */
public function __construct($key) { public function __construct($key) {
$this->key = DocumentationHelper::clean_page_url($key); $this->key = DocumentationHelper::clean_page_url($key);
} }
/** /**
* Get the title of this module. * Get the title of this module.
@ -103,7 +110,7 @@ class DocumentationEntity extends ViewableData {
/** /**
* Returns the web accessible link to this entity. * Returns the web accessible link to this entity.
* *
* Includes the version information * Includes the version information
* *
* @return string * @return string
*/ */
@ -116,7 +123,7 @@ class DocumentationEntity extends ViewableData {
); );
} else { } else {
$base = Controller::join_links( $base = Controller::join_links(
Config::inst()->get('DocumentationViewer', 'link_base'), Config::inst()->get('DocumentationViewer', 'link_base'),
$this->getLanguage(), $this->getLanguage(),
$this->getKey(), $this->getKey(),
'/' '/'
@ -130,12 +137,12 @@ class DocumentationEntity extends ViewableData {
} }
return Controller::join_links( return Controller::join_links(
$base, $base,
$this->getVersion(), $this->getVersion(),
'/' '/'
); );
} }
/** /**
* @return string * @return string
*/ */
@ -213,6 +220,22 @@ class DocumentationEntity extends ViewableData {
return $this->version; return $this->version;
} }
/**
* @param string
*/
public function setBranch($branch) {
$this->branch = $branch;
return $this;
}
/**
* @return float
*/
public function getBranch() {
return $this->branch;
}
/** /**
* @return string * @return string
*/ */
@ -250,8 +273,8 @@ class DocumentationEntity extends ViewableData {
/** /**
* Returns an integer value based on if a given version is the latest * Returns an integer value based on if a given version is the latest
* version. Will return -1 for if the version is older, 0 if versions are * version. Will return -1 for if the version is older, 0 if versions are
* the same and 1 if the version is greater than. * the same and 1 if the version is greater than.
* *
* @param string $version * @param string $version
@ -269,8 +292,9 @@ class DocumentationEntity extends ViewableData {
'Key' => $this->key, 'Key' => $this->key,
'Path' => $this->getPath(), 'Path' => $this->getPath(),
'Version' => $this->getVersion(), 'Version' => $this->getVersion(),
'Branch' => $this->getBranch(),
'IsStable' => $this->getIsStable(), 'IsStable' => $this->getIsStable(),
'Language' => $this->getLanguage() 'Language' => $this->getLanguage()
); );
} }
} }

View File

@ -25,6 +25,21 @@ In YAML this looks like:
Path: "framework/docs/" Path: "framework/docs/"
Title: "Framework Documentation" Title: "Framework Documentation"
###Branch aliases for the edit link (optional)
When using entities with multiple versions, one of the branches of documentation may be a development version. For example the 'master' branch. You may have an internally assigned version number for this registered in your .yml configuration.
If this version number is not the same as the branch name on the git repository the `getEditLinks` method will return an incorrect link to go and edit the documentation. In this case you can simply set an optional `branch` property on the entity which will be used in the edit link instead.
Example:
:::yml
DocumentationManifest:
register_entities:
-
Path: "framework/docs/"
Title: "Framework Documentation"
Version: "1.0"
Branch: "master"
## Permalinks ## Permalinks
@ -92,4 +107,4 @@ headers you use.
## Images and Files ## Images and Files
If you want to attach images and other assets to a page you need to bundle those If you want to attach images and other assets to a page you need to bundle those
in a directory called _images at the same level as your documentation. in a directory called _images at the same level as your documentation.