MAJOR: enable the use of custom metadata and page sorting

This commit is contained in:
martimiz 2013-05-22 18:35:26 +02:00
parent cdb55f94f8
commit 5400ba2afc
3 changed files with 156 additions and 6 deletions

View File

@ -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;
}
/**

View File

@ -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 = '/(?<key>[A-Za-z][A-Za-z0-9_-]+)[\t]*:[\t]*(?<value>[^:\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]);
}
}
}
}
}
}
}

View File

@ -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:
<!--
pagenumber: 1
title: A custom title
-->
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.