ENHANCEMENT: moved away from DebugView display / layout

This commit is contained in:
Will Rossiter 2010-03-04 10:18:02 +00:00
parent ee8eb4e7b5
commit f78967a69d
4 changed files with 172 additions and 124 deletions

View File

@ -6,11 +6,7 @@
* Reads the bundled markdown files from doc/ folders and displays output in
* a formatted page
*
* @todo
* - We should move away from relying on DebugViewer. We could even use the actual
* standard template system for the layout
*
* - Abstract html / css out from DebugViewer
* @todo Tidy up template / styling
*
* @package sapphiredocs
*/
@ -39,9 +35,11 @@ class DocumentationViewer extends Controller {
$this->writeHeader();
$base = Director::baseURL();
$readme = ($this->readmeExists('sapphire')) ? "<a href=''>Read Me</a>" : false;
// write the main content (sapphire) on the left
echo "<div id='LeftColumn'><div class='box'>";
echo "<h2>Sapphire</h2>";
echo "<div id='Home'><div id='LeftColumn'><div class='box'>";
echo "<h2>sapphire $readme</h2>";
$this->generateNestedTree('sapphire');
@ -50,6 +48,9 @@ class DocumentationViewer extends Controller {
$modules = scandir(BASE_PATH);
// modules which are not documented
$undocumented = array();
// generate a list of module documentation (not core)
if($modules) {
foreach($modules as $module) {
@ -57,51 +58,37 @@ class DocumentationViewer extends Controller {
$ignored_modules = array('sapphire', 'assets', 'themes');
if(!in_array($module, $ignored_modules) && !in_array($module, self::$ignored_files) && is_dir(BASE_PATH .'/'. $module)) {
echo "<div class='box'><h2>". $module ."</h2>";
// see if docs folder is present
$subfolders = scandir(BASE_PATH .'/'. $module);
if($subfolders && in_array('doc', $subfolders)) {
$readme = ($filename = $this->readmeExists($module)) ? "<a href='todo'>Read Me</a>" : false;
echo "<div class='box'><h2>". $module .' '. $readme."</h2>";
$this->generateNestedTree($module);
echo "</div>";
}
else {
echo "<p class='noDocs'>No Documentation For Module</p>";
$undocumented[] = $module;
}
echo "</div>";
}
}
}
// for each of the modules. Display them here
echo "</div>";
echo "</div></div><div class='undocumentedModules'>";
if($undocumented) {
echo "<p>Undocumented Modules: ";
echo implode(', ', $undocumented);
}
$this->writeFooter();
}
/**
* @todo - This is nasty, ripped out of DebugView.
*/
function writeHeader() {
echo '<!DOCTYPE html>
<html>
<head>
<base href="'. Director::absoluteBaseURL() .'> "
<title>' . htmlentities($_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI']) . '</title>
<link rel="stylesheet" href="sapphiredocs/css/DocumentationViewer.css" type="text/css">
</head>
<body>
<div class="header">SilverStripe</div>
<div class="info">
<h1>SilverStripe Documentation</h1>
<p class="breadcrumbs"><a href="dev/docs/">docs</a></p></div>';
}
function writeFooter() {
echo "</body></html>";
}
/**
* Parse a given individual markdown page
*
@ -116,7 +103,7 @@ class DocumentationViewer extends Controller {
if(!stripos($class, '.md')) $class .= '.md';
$this->writeHeader();
$this->writeHeader($class, $module);
$base = Director::baseURL();
@ -140,6 +127,63 @@ class DocumentationViewer extends Controller {
$this->writeFooter();
}
/**
* @todo - This is nasty, ripped out of DebugView.
*/
function writeHeader($class = "", $module = "") {
$breadcrumbs = false;
if($module) {
$parts = array();
$parts[] = "<a href='dev/docs/'>Documentation Home</a>";
$parts[] = "<a href='dev/docs/$module'>$module</a>";
if($class) $parts[] = $this->formatStringForTitle($class);
$breadcrumbs = implode("&nbsp;&raquo;&nbsp;", $parts);
$breadcrumbs = '<p class="breadcrumbs">'. $breadcrumbs .'</p>';
}
echo '<!DOCTYPE html>
<html>
<head>
<base href="'. Director::absoluteBaseURL() .'> "
<title>' . htmlentities($_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI']) . '</title>
<link rel="stylesheet" href="sapphiredocs/css/DocumentationViewer.css" type="text/css">
</head>
<body>
<div id="Container">
<div id="Header">
<h1><a href="dev/docs/">SilverStripe Documentation</a></h1>
'.$breadcrumbs.'
</div>
';
}
function writeFooter() {
echo "</div></body></html>";
}
/**
* Work out if a module contains a readme
*
* @param String - Module to check
* @return bool|String - of path
*/
private function readmeExists($module) {
$children = scandir(BASE_PATH.'/'.$module);
$readmeOptions = array('readme', 'readme.md', 'readme.txt');
if($children) {
foreach($children as $i => $file) {
if(in_array(strtolower($file), $readmeOptions)) return $file;
}
}
return false;
}
/**
* Find a documentation page within a given module.
*
@ -196,13 +240,13 @@ class DocumentationViewer extends Controller {
if($handle) {
while (false !== ($file = readdir($handle))) {
if(!in_array($file, self::$ignored_files)) {
$newPath = $path.$file;
$newPath = $path.'/'.$file;
// if the file is a dir nest the pages
if(is_dir($newPath)) {
// if this has a number
echo "<li class='level'>". $this->formatStringForTitle($file) ."</li>";
echo "<li class='folder'>". $this->formatStringForTitle($file) ."</li>";
$this->recursivelyGenerateTree($newPath, $module);
}
@ -234,6 +278,9 @@ class DocumentationViewer extends Controller {
// change - to spaces
$title = str_ireplace('-', ' ', $title);
// remove extension
$title = str_ireplace('.md', ' ', $title);
return $title;
}
}

View File

@ -6,23 +6,25 @@
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding: 0;}
html { background: #eee;}
body { font: 14px/1.1 Helvetica,Arial,sans-serif; color: #333; }
html { background: #f4f4f4;}
body { font: 14px/1.1 Arial,sans-serif; color: #444; }
a { color: #1389ce; text-decoration: none; }
a:hover { text-decoration: underline;}
p {
font-size: 14px;
line-height: 21px;
margin-bottom: 21px;
line-height: 22px;
margin-bottom: 22px;
}
ul { margin: 0 0 21px 21px; }
li { font-size: 14px; line-height: 21px;}
ul { margin: 8px 16px 20px 20px; }
li { font-size: 12px; line-height: 18px; margin-bottom: 8px;}
h1 { font-size: 18px; margin-bottom: 18px; }
h2 { font-size: 16px; margin-bottom: 18px; }
h3 { font-size: 14px; margin-bottom: 18px; }
h4 { font-size: 12px; margin-bottom: 9px; }
h1 { font-size: 24px; margin-bottom: 18px; }
h2 { font-size: 18px; margin-bottom: 16px; }
h3 { font-size: 16px; margin-bottom: 16px; }
h4 { font-size: 14px; margin-bottom: 8px; }
pre {
margin-bottom: 18px;
@ -32,92 +34,50 @@ pre {
padding: 12px;
}
/* Header Banner */
.info {
border:1px solid #bbb;
border-width: 1px 0;
background-color:#ccdef3;
padding: 12px;
margin-bottom: 18px;
}
.info h1 {
margin: 0;
padding: 0;
color: #333;
font-size: 30px;
letter-spacing: -2px;
}
#Container { width: 860px; margin: 20px auto; padding: 20px; background: #fff; overflow: hidden; }
.info h3 {
margin: 4px 0;
color: #333;
font-size: 14px;
}
#Header { border-bottom: 3px solid #535360; padding-top: 10px; margin-bottom: 30px; }
#Header h1 { margin-bottom: 9px;}
#Header h1 a { text-decoration: none; font-size: 30px; color: #333; letter-spacing: -1px;}
.info p {
color: #484f57;
margin: 0;
}
.header {
margin:0;
background-color:#666673;
text-align: right;
font-size: 12px;
padding: 8px 12px;
color: #fff;
background-image:url(../../cms/images/mainmenu/top-bg.gif);
}
.trace { padding:6px 12px; }
.trace li { font-size:14px; margin:6px 0; }
pre span { color:#999;}
pre .error { color:#f00; }
/* Status Box */
.status {
padding:10px 20px 10px 40px;
margin-bottom: 12px;
}
.status h2 { margin: 0; }
.pass {
color:#006600;
background:#E2F9E3 url(../../cms/images/alert-good.gif) no-repeat scroll 7px 50%;
border:1px solid #8DD38D;
}
.fail {
color:#C80700;
background:#FFE9E9 url(../../cms/images/alert-bad.gif) no-repeat scroll 7px 50%;
border:1px solid #C80700;
}
.pending {
background: #fefcc5;
border: 1px solid #dedc51;
}
.buildCompleted { display: none; }
.failure span { color:#C80700; font-weight:bold; }
#Header .breadcrumbs { font-size: 12px; }
#LeftColumn {
width: 60%;
width: 600px;
float: left;
}
#RightColumn {
width: 40%;
width: 240px;
float: right;
}
.box {
background: #fff;
padding: 12px;
margin: 0 12px 12px 12px;
border: 1px solid #ddd;
#Home #LeftColumn { width: 500px; }
#Home #RightColumn { width: 340px; }
#Home .box {
margin: 0 12px 12px 0px;
border: 1px solid #d8d8d8;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
.box h2 {
background: #535360;
border: 1px solid #535360;
-moz-border-top-radius: 4px;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
padding: 6px 8px;
font-weight: 500;
color: #fff;
font-size: 13px;
}
.box h2 a {
background: url(../images/readme.png) no-repeat right center;
padding: 2px 20px 0 0;
font-size: 11px;
color: #fff;
display: block;
float: right;
}
#RightColumn .box {
margin: 0 12px 12px 0;
}
@ -130,6 +90,19 @@ pre .error { color:#f00; }
}
.box ul.tree li {
list-style: none;
font-size: 12px;
}
.box ul.tree li.folder {
background: #d5eefd;
font-size: 12px;
color: #29688c;
margin-bottom: 9px;
border: 1px solid #d5eefd;
padding: 2px 6px;
-moz-border-radius: 4px;
-webkit-border-radius: 4px;
}
.undocumentedModules {
clear: both;
padding-top: 10px;
font-style: italic;
}

View File

@ -0,0 +1,28 @@
# Writing Documentation #
Your documentation needs to go in the specific modules doc folder which it refers mostly too. For example if you want to document
a feature of your custom module 'MyModule' you need to create markdown files in mymodule/doc/.
The files have to end with the __.md__ extension. The documentation viewer will automatically replace hyphens (-) with spaces (since you cannot
have spaces easily in some file systems).
## Syntax ##
This uses a customized markdown extra parser. To view the syntax for page formatting check out [http://daringfireball.net/projects/markdown/syntax][Daring Fireball]
## Creating Hierarchy ##
The document viewer supports folder structure. There is no limit on depth or number of sub categories you can create.
## Customizing Page Order ##
Sometimes you will have pages which you want at the top of the documentation viewer summary. Pages like Getting-Started will come after Advanced-Usage
due to the default alphabetical ordering.
To handle this you can use a number prefix for example __01-My-First-Folder__ which would be the first folder in the list.
DocumentationViewer will remove the __01-__ from the name as well so you don't need to worry about labels for your folders with numbers. It will be
outputted in the front end as __My First Folder__

BIN
images/readme.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B