Merge pull request #30 from Martimiz/meta-sort-20130522

MAJOR: enable the use of custom metadata and page sorting
This commit is contained in:
Ingo Schommer 2013-06-10 00:42:32 -07:00
commit 2d7c1499d7
4 changed files with 167 additions and 8 deletions

View File

@ -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);

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 = (bool) $allow;
}
/**
* 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,16 +261,19 @@ class DocumentationPage extends ViewableData {
*
* @return string
*/
function getMarkdown() {
function getMarkdown($removeMetaData = false) {
try {
$path = $this->getPath(true);
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, $removeMetaData);
}
return $md;
}
}
}
catch(InvalidArgumentException $e) {}
@ -274,4 +291,42 @@ class DocumentationPage extends ViewableData {
function getHTML($version, $lang = 'en') {
return DocumentationParser::parse($this, $this->entity->getRelativeLink($version, $lang));
}
/**
* 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, $removeMetaData = false) {
if($md && DocumentationService::meta_comments_enabled()) {
// get the text up to the first whiteline
$extPattern = "/^(.+)\n(\r)*\n/Uis";
$matches = preg_match($extPattern, $md, $block);
if($matches && $block[1]) {
$metaDataFound = false;
// find the key/value pairs
$intPattern = '/(?<key>[A-Za-z][A-Za-z0-9_-]+)[\t]*:[\t]*(?<value>[^:\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);
}
}
}
}
}

View File

@ -54,5 +54,51 @@ 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.
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.