From 5400ba2afc74b6407693b60e354eed8fc13005ba Mon Sep 17 00:00:00 2001 From: martimiz Date: Wed, 22 May 2013 18:35:26 +0200 Subject: [PATCH 1/2] MAJOR: enable the use of custom metadata and page sorting --- code/DocumentationService.php | 62 ++++++++++++++++++++++++++++++- code/models/DocumentationPage.php | 49 ++++++++++++++++++++++-- docs/en/Configuration-Options.md | 51 +++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 6 deletions(-) diff --git a/code/DocumentationService.php b/code/DocumentationService.php index 453fba1..38c1b9b 100755 --- a/code/DocumentationService.php +++ b/code/DocumentationService.php @@ -76,6 +76,20 @@ class DocumentationService { * @var bool */ private static $automatic_registration = true; + + /** + * by default pagenumbers start high at 10.000 + * + * @var integer + */ + private static $pagenumber_start_at = 10000; + + /** + * allow the use of key/value pairs in comments + * + * @var boolean + */ + private static $meta_comments_enabled = false; /** * Return the allowed extensions @@ -138,6 +152,43 @@ class DocumentationService { public static function automatic_registration_enabled() { return self::$automatic_registration; } + + /** + * set the number to start default pagenumbering, allowing room for + * custom pagenumbers below. + * + * @param int $number + */ + public static function start_pagenumbers_at($number = 10000) { + if (is_int($number)) self::$pagenumber_start_at = $number; + } + + /** + * return the startlevel for default pagenumbering + * + * @return int + */ + public static function get_pagenumber_start_at() { + return self::$pagenumber_start_at; + } + + /** + * Allow the use of key/value pairs in comments? + * + * @param bool $allow + */ + public static function enable_meta_comments($allow = true) { + self::$meta_comments_enabled = ($allow)? true: false; + } + + /** + * can we use key/value pairs + * + * @return bool + */ + public static function meta_comments_enabled() { + return self::$meta_comments_enabled; + } /** * Return the entities which are listed for documentation. Optionally only @@ -459,6 +510,7 @@ class DocumentationService { */ public static function get_pages_from_folder($entity, $relativePath = false, $recursive = true, $version = 'trunk', $lang = 'en') { $output = new ArrayList(); + $metaCommentsEnabled = self::meta_comments_enabled(); $pages = array(); if(!$entity instanceof DocumentationEntity) @@ -475,6 +527,7 @@ class DocumentationService { } if(count($pages) > 0) { + $pagenumber = self::get_pagenumber_start_at(); natsort($pages); foreach($pages as $key => $pagePath) { @@ -497,12 +550,17 @@ class DocumentationService { // does this page act as a folder? $path = $page->getPath(); if (is_dir($path)) { $page->setIsFolder(true); } - + + $page->setPagenumber($pagenumber++); + + // we need the markdown to get the comments + if ($metaCommentsEnabled) $page->getMarkdown(); + $output->push($page); } } - return $output; + return ($metaCommentsEnabled)? $output->sort('pagenumber') : $output; } /** diff --git a/code/models/DocumentationPage.php b/code/models/DocumentationPage.php index 792f8ff..02b488e 100755 --- a/code/models/DocumentationPage.php +++ b/code/models/DocumentationPage.php @@ -42,6 +42,12 @@ class DocumentationPage extends ViewableData { */ protected $isFolder = false; + /** + * + * @var integer + */ + protected $pagenumber = 0; + /** * @param Boolean */ @@ -56,6 +62,14 @@ class DocumentationPage extends ViewableData { return $this->isFolder; } + /** + * + * @param int $number + */ + public function setPagenumber($number = 0) { + if (is_int($number )) $this->pagenumber = $number; + } + /** * @return DocumentationEntity */ @@ -247,10 +261,13 @@ class DocumentationPage extends ViewableData { if($path) { $ext = $this->getExtension(); - - if(DocumentationService::is_valid_extension($ext)) { - return file_get_contents($path); - } + + if(empty($ext) || DocumentationService::is_valid_extension($ext)) { + if ($md = file_get_contents($path)) { + if ($this->title != 'Index') $this->getMetadataFromComments($md); + } + return $md; + } } } catch(InvalidArgumentException $e) {} @@ -268,4 +285,28 @@ class DocumentationPage extends ViewableData { function getHTML($version, $lang = 'en') { return DocumentationParser::parse($this, $this->entity->getRelativeLink($version, $lang)); } + + /** + * get metadata from the first html comments block in the page + * + * @param DocumentationPage $md + */ + public function getMetadataFromComments($md = '') { + if($md && DocumentationService::meta_comments_enabled()) { + //$pattern = '/^/Uis'; + $pattern = "/^(.+)\n(\r)*\n/Uis"; + $matches = preg_match($pattern, $md, $block); + if($matches && $block[1]) { + $pattern = '/(?[A-Za-z][A-Za-z0-9_-]+)[\t]*:[\t]*(?[^:\n\r\/]+)/x'; + $matches = preg_match_all($pattern, $block[1], $meta); + foreach($meta['key'] as $index => $key) { + if(isset($meta['value'][$index])) { + if (property_exists(get_class(), $key)) { + $this->setMetaData($key, $meta['value'][$index]); + } + } + } + } + } + } } \ No newline at end of file diff --git a/docs/en/Configuration-Options.md b/docs/en/Configuration-Options.md index 89aaf64..c3581f4 100755 --- a/docs/en/Configuration-Options.md +++ b/docs/en/Configuration-Options.md @@ -54,5 +54,56 @@ to new structures. )); +## Custom metadata and pagesorting +Custom metadata can be added to the head of the MarkDown file like this: + + pagenumber: 1 + title: A custom title + + +Make sure to add an empty line to separate the metadata from the content of +the file. To make the metadata invisible on the page, you can use a comment tag: + + + +You now need to explicitly enable the use of metadata by adding the following to +your _config.php: + + ```php + DocumentationService::enable_meta_comments(); + ``` + +**Note:** SilverStripe needs to read the contents of each page to retrieve the +metadata. This is expensive, so if you do not plan to use custom sorting, +do not enable this feature: + +### Custom page sorting + +By default pages in the lefthand menu are sorted alphabetically. Adding a +pagenumber to the metadata, like in the example above, allows for custom +pagenumbering. + +**Note:** although folders appear in the menu as 'pages', you obviously can't +number them, so you need to number their index.php page instead. + +Pages that have no custom pagenumber, keep their original +order, but for them not to interfere with custom sort, they also receive a +pagenumber, starting at 10.000. + +You can change this starting point for default pagenumbers: + + ```php + DocumentationService:: start_pagenumbers_at(80); + ``` + +### Other key-value pairs + +Basically all DocumentationPage properties can be added to the metadata comment +block. Beware that the outcome isn't always predictable. Adding a title +property to the block will change the menu title, but the breadcrumbs +are at this time not yet supported. \ No newline at end of file From 227289575a3bca600e9dc7722f0f31344a2eac80 Mon Sep 17 00:00:00 2001 From: martimiz Date: Wed, 22 May 2013 21:35:03 +0200 Subject: [PATCH 2/2] MEDIUM: remove metadata from the current page --- code/DocumentationParser.php | 2 +- code/DocumentationService.php | 2 +- code/models/DocumentationPage.php | 34 ++++++++++++++++++++++--------- docs/en/Configuration-Options.md | 7 +------ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/code/DocumentationParser.php b/code/DocumentationParser.php index fe5374c..61bbe54 100755 --- a/code/DocumentationParser.php +++ b/code/DocumentationParser.php @@ -44,7 +44,7 @@ class DocumentationParser { public static function parse(DocumentationPage $page, $baselink = null) { if(!$page || (!$page instanceof DocumentationPage)) return false; - $md = $page->getMarkdown(); + $md = $page->getMarkdown(true); // Pre-processing $md = self::rewrite_image_links($md, $page); diff --git a/code/DocumentationService.php b/code/DocumentationService.php index 38c1b9b..4b3747f 100755 --- a/code/DocumentationService.php +++ b/code/DocumentationService.php @@ -178,7 +178,7 @@ class DocumentationService { * @param bool $allow */ public static function enable_meta_comments($allow = true) { - self::$meta_comments_enabled = ($allow)? true: false; + self::$meta_comments_enabled = (bool) $allow; } /** diff --git a/code/models/DocumentationPage.php b/code/models/DocumentationPage.php index 02b488e..35917d4 100755 --- a/code/models/DocumentationPage.php +++ b/code/models/DocumentationPage.php @@ -255,7 +255,7 @@ class DocumentationPage extends ViewableData { * * @return string */ - function getMarkdown() { + function getMarkdown($removeMetaData = false) { try { $path = $this->getPath(true); @@ -264,7 +264,7 @@ class DocumentationPage extends ViewableData { if(empty($ext) || DocumentationService::is_valid_extension($ext)) { if ($md = file_get_contents($path)) { - if ($this->title != 'Index') $this->getMetadataFromComments($md); + if ($this->title != 'Index') $this->getMetadataFromComments($md, $removeMetaData); } return $md; } @@ -287,25 +287,39 @@ class DocumentationPage extends ViewableData { } /** - * get metadata from the first html comments block in the page + * get metadata from the first html block in the page, then remove the + * block on request * * @param DocumentationPage $md + * @param bool $remove */ - public function getMetadataFromComments($md = '') { + public function getMetadataFromComments(&$md, $removeMetaData = false) { if($md && DocumentationService::meta_comments_enabled()) { - //$pattern = '/^/Uis'; - $pattern = "/^(.+)\n(\r)*\n/Uis"; - $matches = preg_match($pattern, $md, $block); + + // get the text up to the first whiteline + $extPattern = "/^(.+)\n(\r)*\n/Uis"; + $matches = preg_match($extPattern, $md, $block); if($matches && $block[1]) { - $pattern = '/(?[A-Za-z][A-Za-z0-9_-]+)[\t]*:[\t]*(?[^:\n\r\/]+)/x'; - $matches = preg_match_all($pattern, $block[1], $meta); + $metaDataFound = false; + + // find the key/value pairs + $intPattern = '/(?[A-Za-z][A-Za-z0-9_-]+)[\t]*:[\t]*(?[^:\n\r\/]+)/x'; + $matches = preg_match_all($intPattern, $block[1], $meta); + foreach($meta['key'] as $index => $key) { if(isset($meta['value'][$index])) { + + // check if a property exists for this key if (property_exists(get_class(), $key)) { $this->setMetaData($key, $meta['value'][$index]); + $metaDataFound = true; } } - } + } + // optionally remove the metadata block (only on the page that is displayed) + if ($metaDataFound && $removeMetaData) { + $md = preg_replace($extPattern, '', $md); + } } } } diff --git a/docs/en/Configuration-Options.md b/docs/en/Configuration-Options.md index c3581f4..0c62420 100755 --- a/docs/en/Configuration-Options.md +++ b/docs/en/Configuration-Options.md @@ -63,12 +63,7 @@ Custom metadata can be added to the head of the MarkDown file like this: Make sure to add an empty line to separate the metadata from the content of -the file. To make the metadata invisible on the page, you can use a comment tag: - - +the file. You now need to explicitly enable the use of metadata by adding the following to your _config.php: