mirror of
https://github.com/silverstripe/silverstripe-docsviewer
synced 2024-10-22 09:05:56 +00:00
ENHANCEMENT: moved away from DebugView display / layout
This commit is contained in:
parent
ee8eb4e7b5
commit
f78967a69d
@ -6,11 +6,7 @@
|
|||||||
* Reads the bundled markdown files from doc/ folders and displays output in
|
* Reads the bundled markdown files from doc/ folders and displays output in
|
||||||
* a formatted page
|
* a formatted page
|
||||||
*
|
*
|
||||||
* @todo
|
* @todo Tidy up template / styling
|
||||||
* - 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
|
|
||||||
*
|
*
|
||||||
* @package sapphiredocs
|
* @package sapphiredocs
|
||||||
*/
|
*/
|
||||||
@ -39,9 +35,11 @@ class DocumentationViewer extends Controller {
|
|||||||
$this->writeHeader();
|
$this->writeHeader();
|
||||||
$base = Director::baseURL();
|
$base = Director::baseURL();
|
||||||
|
|
||||||
|
$readme = ($this->readmeExists('sapphire')) ? "<a href=''>Read Me</a>" : false;
|
||||||
|
|
||||||
// write the main content (sapphire) on the left
|
// write the main content (sapphire) on the left
|
||||||
echo "<div id='LeftColumn'><div class='box'>";
|
echo "<div id='Home'><div id='LeftColumn'><div class='box'>";
|
||||||
echo "<h2>Sapphire</h2>";
|
echo "<h2>sapphire $readme</h2>";
|
||||||
|
|
||||||
$this->generateNestedTree('sapphire');
|
$this->generateNestedTree('sapphire');
|
||||||
|
|
||||||
@ -50,6 +48,9 @@ class DocumentationViewer extends Controller {
|
|||||||
|
|
||||||
$modules = scandir(BASE_PATH);
|
$modules = scandir(BASE_PATH);
|
||||||
|
|
||||||
|
// modules which are not documented
|
||||||
|
$undocumented = array();
|
||||||
|
|
||||||
// generate a list of module documentation (not core)
|
// generate a list of module documentation (not core)
|
||||||
if($modules) {
|
if($modules) {
|
||||||
foreach($modules as $module) {
|
foreach($modules as $module) {
|
||||||
@ -57,51 +58,37 @@ class DocumentationViewer extends Controller {
|
|||||||
$ignored_modules = array('sapphire', 'assets', 'themes');
|
$ignored_modules = array('sapphire', 'assets', 'themes');
|
||||||
|
|
||||||
if(!in_array($module, $ignored_modules) && !in_array($module, self::$ignored_files) && is_dir(BASE_PATH .'/'. $module)) {
|
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
|
// see if docs folder is present
|
||||||
$subfolders = scandir(BASE_PATH .'/'. $module);
|
$subfolders = scandir(BASE_PATH .'/'. $module);
|
||||||
|
|
||||||
if($subfolders && in_array('doc', $subfolders)) {
|
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);
|
$this->generateNestedTree($module);
|
||||||
|
echo "</div>";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
echo "<p class='noDocs'>No Documentation For Module</p>";
|
$undocumented[] = $module;
|
||||||
}
|
}
|
||||||
echo "</div>";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// for each of the modules. Display them here
|
// 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();
|
$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
|
* Parse a given individual markdown page
|
||||||
*
|
*
|
||||||
@ -116,7 +103,7 @@ class DocumentationViewer extends Controller {
|
|||||||
|
|
||||||
if(!stripos($class, '.md')) $class .= '.md';
|
if(!stripos($class, '.md')) $class .= '.md';
|
||||||
|
|
||||||
$this->writeHeader();
|
$this->writeHeader($class, $module);
|
||||||
|
|
||||||
$base = Director::baseURL();
|
$base = Director::baseURL();
|
||||||
|
|
||||||
@ -140,6 +127,63 @@ class DocumentationViewer extends Controller {
|
|||||||
$this->writeFooter();
|
$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(" » ", $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.
|
* Find a documentation page within a given module.
|
||||||
*
|
*
|
||||||
@ -196,13 +240,13 @@ class DocumentationViewer extends Controller {
|
|||||||
if($handle) {
|
if($handle) {
|
||||||
while (false !== ($file = readdir($handle))) {
|
while (false !== ($file = readdir($handle))) {
|
||||||
if(!in_array($file, self::$ignored_files)) {
|
if(!in_array($file, self::$ignored_files)) {
|
||||||
$newPath = $path.$file;
|
$newPath = $path.'/'.$file;
|
||||||
|
|
||||||
// if the file is a dir nest the pages
|
// if the file is a dir nest the pages
|
||||||
if(is_dir($newPath)) {
|
if(is_dir($newPath)) {
|
||||||
|
|
||||||
// if this has a number
|
// 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);
|
$this->recursivelyGenerateTree($newPath, $module);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -234,6 +278,9 @@ class DocumentationViewer extends Controller {
|
|||||||
// change - to spaces
|
// change - to spaces
|
||||||
$title = str_ireplace('-', ' ', $title);
|
$title = str_ireplace('-', ' ', $title);
|
||||||
|
|
||||||
|
// remove extension
|
||||||
|
$title = str_ireplace('.md', ' ', $title);
|
||||||
|
|
||||||
return $title;
|
return $title;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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;}
|
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;}
|
html { background: #f4f4f4;}
|
||||||
body { font: 14px/1.1 Helvetica,Arial,sans-serif; color: #333; }
|
body { font: 14px/1.1 Arial,sans-serif; color: #444; }
|
||||||
|
|
||||||
|
a { color: #1389ce; text-decoration: none; }
|
||||||
|
a:hover { text-decoration: underline;}
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 21px;
|
line-height: 22px;
|
||||||
margin-bottom: 21px;
|
margin-bottom: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul { margin: 0 0 21px 21px; }
|
ul { margin: 8px 16px 20px 20px; }
|
||||||
li { font-size: 14px; line-height: 21px;}
|
li { font-size: 12px; line-height: 18px; margin-bottom: 8px;}
|
||||||
|
|
||||||
|
|
||||||
h1 { font-size: 18px; margin-bottom: 18px; }
|
h1 { font-size: 24px; margin-bottom: 18px; }
|
||||||
h2 { font-size: 16px; margin-bottom: 18px; }
|
h2 { font-size: 18px; margin-bottom: 16px; }
|
||||||
h3 { font-size: 14px; margin-bottom: 18px; }
|
h3 { font-size: 16px; margin-bottom: 16px; }
|
||||||
h4 { font-size: 12px; margin-bottom: 9px; }
|
h4 { font-size: 14px; margin-bottom: 8px; }
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
margin-bottom: 18px;
|
margin-bottom: 18px;
|
||||||
@ -32,92 +34,50 @@ pre {
|
|||||||
padding: 12px;
|
padding: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Header Banner */
|
#Container { width: 860px; margin: 20px auto; padding: 20px; background: #fff; overflow: hidden; }
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info h3 {
|
#Header { border-bottom: 3px solid #535360; padding-top: 10px; margin-bottom: 30px; }
|
||||||
margin: 4px 0;
|
#Header h1 { margin-bottom: 9px;}
|
||||||
color: #333;
|
#Header h1 a { text-decoration: none; font-size: 30px; color: #333; letter-spacing: -1px;}
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.info p {
|
#Header .breadcrumbs { font-size: 12px; }
|
||||||
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; }
|
|
||||||
|
|
||||||
#LeftColumn {
|
#LeftColumn {
|
||||||
width: 60%;
|
width: 600px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
#RightColumn {
|
#RightColumn {
|
||||||
width: 40%;
|
width: 240px;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box {
|
#Home #LeftColumn { width: 500px; }
|
||||||
background: #fff;
|
#Home #RightColumn { width: 340px; }
|
||||||
padding: 12px;
|
#Home .box {
|
||||||
margin: 0 12px 12px 12px;
|
margin: 0 12px 12px 0px;
|
||||||
border: 1px solid #ddd;
|
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 {
|
#RightColumn .box {
|
||||||
margin: 0 12px 12px 0;
|
margin: 0 12px 12px 0;
|
||||||
}
|
}
|
||||||
@ -130,6 +90,19 @@ pre .error { color:#f00; }
|
|||||||
}
|
}
|
||||||
.box ul.tree li {
|
.box ul.tree li {
|
||||||
list-style: none;
|
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;
|
||||||
|
}
|
28
doc/Writing-Documentation.md
Normal file
28
doc/Writing-Documentation.md
Normal 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
BIN
images/readme.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 342 B |
Loading…
x
Reference in New Issue
Block a user