From af33599e198f89a446055e7c1333ec27e66c05e6 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Wed, 16 Oct 2013 14:45:23 +0200 Subject: [PATCH 01/11] Add doc module (WIP) refs #4820 --- .../controllers/IndexController.php | 15 +++ .../controllers/ViewController.php | 52 +++++++++++ .../application/views/scripts/view/view.phtml | 10 ++ .../doc/library/Doc/MarkdownFileIterator.php | 27 ++++++ modules/doc/library/Doc/Parser.php | 93 +++++++++++++++++++ 5 files changed, 197 insertions(+) create mode 100644 modules/doc/application/controllers/IndexController.php create mode 100644 modules/doc/application/controllers/ViewController.php create mode 100644 modules/doc/application/views/scripts/view/view.phtml create mode 100644 modules/doc/library/Doc/MarkdownFileIterator.php create mode 100644 modules/doc/library/Doc/Parser.php diff --git a/modules/doc/application/controllers/IndexController.php b/modules/doc/application/controllers/IndexController.php new file mode 100644 index 000000000..a83cbdec5 --- /dev/null +++ b/modules/doc/application/controllers/IndexController.php @@ -0,0 +1,15 @@ +_forward('index', 'view'); + } +} +// @codingStandardsIgnoreEnd diff --git a/modules/doc/application/controllers/ViewController.php b/modules/doc/application/controllers/ViewController.php new file mode 100644 index 000000000..b2174872d --- /dev/null +++ b/modules/doc/application/controllers/ViewController.php @@ -0,0 +1,52 @@ +_helper->viewRenderer->setRender('view'); + } + + /** + * Populate view + * + * @param string $dir + */ + private function populateView($dir) + { + $parser = new DocParser(); + list($html, $toc) = $parser->parseDirectory($dir); + $this->view->html = $html; + $this->view->toc = $toc; + } + + public function indexAction() + { + $this->populateView(Icinga::app()->getApplicationDir('/../doc')); + } + + /** + * Provide run-time dispatching of module documentation + * + * @param string $methodName + * @param array $args + */ + public function __call($methodName, $args) + { + $moduleManager = Icinga::app()->getModuleManager(); + $moduleName = substr($methodName, 0, -6); // Strip 'Action' suffix + if ($moduleManager->hasEnabled($moduleName)) { + $this->populateView($moduleManager->getModuleDir($moduleName, '/doc')); + } else { + parent::__call($methodName, $args); + } + } +} +// @codingStandardsIgnoreEnd diff --git a/modules/doc/application/views/scripts/view/view.phtml b/modules/doc/application/views/scripts/view/view.phtml new file mode 100644 index 000000000..c9b7cb46b --- /dev/null +++ b/modules/doc/application/views/scripts/view/view.phtml @@ -0,0 +1,10 @@ +
+ +
+ diff --git a/modules/doc/library/Doc/MarkdownFileIterator.php b/modules/doc/library/Doc/MarkdownFileIterator.php new file mode 100644 index 000000000..cbf23ac35 --- /dev/null +++ b/modules/doc/library/Doc/MarkdownFileIterator.php @@ -0,0 +1,27 @@ +getInnerIterator()->current(); + if (!$current->isFile()) { + return false; + } + $filename = $current->getFilename(); + $sfx = substr($filename, -3); + return $sfx === false ? false : strtolower($sfx) === '.md'; + } +} diff --git a/modules/doc/library/Doc/Parser.php b/modules/doc/library/Doc/Parser.php new file mode 100644 index 000000000..c96934f7c --- /dev/null +++ b/modules/doc/library/Doc/Parser.php @@ -0,0 +1,93 @@ +openFile(); + } catch (RuntimeException $e) { + throw new Exception($e->getMessage()); + } + if ($fileObject->flock(LOCK_SH) === false) { + throw new Exception('Couldn\'t get the lock'); + } + while (!$fileObject->eof()) { + $line = $fileObject->fgets(); + if ($line && + $line[0] === '#' && + preg_match('/^#+/', $line, $match) === 1 + ) { + // Atx-style + $level = strlen($match[0]); + $heading = trim(strip_tags(substr($line, $level))); + $fragment = urlencode($heading); + $toc[] = array( + 'heading' => $heading, + 'level' => $level, + 'fragment' => $fragment + ); + $line = '' . "\n" . $line; + } elseif ( + $line && + ($line[0] === '=' || $line[0] === '-') && + preg_match('/^[=-]+\s*$/', $line, $match) === 1 + ) { + // Setext + if ($match[0][0] === '=') { + // H1 + $level = 1; + } else { + // H2 + $level = 2; + } + $heading = trim(strip_tags(end($cat))); + $fragment = urlencode($heading); + $toc[] = array( + 'heading' => $heading, + 'level' => $level, + 'fragment' => $fragment + ); + $line = '' . "\n" . $line; + } + $cat[] = $line; + } + $fileObject->flock(LOCK_UN); + } + $html = MarkdownExtra::defaultTransform(implode('', $cat)); + return array($html, $toc); + } +} From 75577cec51baa38b535b39bcca0093f7b9f06105 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Fri, 24 Jan 2014 16:41:37 +0100 Subject: [PATCH 02/11] Modules/doc: Replace Michelf/Markdown with Parsedown refs #4820 --- .../Web/Controller/ActionController.php | 4 +- .../controllers/IndexController.php | 10 +++- .../controllers/ModuleController.php | 44 ++++++++++++++++ .../controllers/ViewController.php | 52 ------------------- .../views/scripts/index/index.phtml | 14 +++++ .../application/views/scripts/view/view.phtml | 10 ---- .../doc/library/Doc/MarkdownFileIterator.php | 3 ++ modules/doc/library/Doc/Parser.php | 11 ++-- 8 files changed, 76 insertions(+), 72 deletions(-) create mode 100644 modules/doc/application/controllers/ModuleController.php delete mode 100644 modules/doc/application/controllers/ViewController.php create mode 100644 modules/doc/application/views/scripts/index/index.phtml delete mode 100644 modules/doc/application/views/scripts/view/view.phtml diff --git a/library/Icinga/Web/Controller/ActionController.php b/library/Icinga/Web/Controller/ActionController.php index 2cd581604..10a534910 100755 --- a/library/Icinga/Web/Controller/ActionController.php +++ b/library/Icinga/Web/Controller/ActionController.php @@ -266,8 +266,6 @@ class ActionController extends Zend_Controller_Action return call_user_func_array(array($this, $deprecatedMethod), $params); } - parent::__call($name, $params); - - return null; + return parent::__call($name, $params); } } diff --git a/modules/doc/application/controllers/IndexController.php b/modules/doc/application/controllers/IndexController.php index a83cbdec5..d18eff5db 100644 --- a/modules/doc/application/controllers/IndexController.php +++ b/modules/doc/application/controllers/IndexController.php @@ -3,13 +3,21 @@ // {{{ICINGA_LICENSE_HEADER}}} // {{{ICINGA_LICENSE_HEADER}}} +use Icinga\Application\Icinga; +use Icinga\Module\Doc\Parser as DocParser; use Icinga\Web\Controller\ActionController; class Doc_IndexController extends ActionController { + /** + * Display the application's documentation + */ public function indexAction() { - $this->_forward('index', 'view'); + $parser = new DocParser(); + list($html, $toc) = $parser->parseDirectory(Icinga::app()->getApplicationDir('/../doc')); + $this->view->html = $html; + $this->view->toc = $toc; } } // @codingStandardsIgnoreEnd diff --git a/modules/doc/application/controllers/ModuleController.php b/modules/doc/application/controllers/ModuleController.php new file mode 100644 index 000000000..f59467505 --- /dev/null +++ b/modules/doc/application/controllers/ModuleController.php @@ -0,0 +1,44 @@ +getModuleManager(); + $moduleName = substr($methodName, 0, -6); // Strip 'Action' suffix + if (!$moduleManager->hasEnabled($moduleName)) { + // TODO(el): Throw a not found exception once the code has been moved to the moduleAction (see TODO above) + return parent::__call($methodName, $args); + } + } +} +// @codingStandardsIgnoreEnd diff --git a/modules/doc/application/controllers/ViewController.php b/modules/doc/application/controllers/ViewController.php deleted file mode 100644 index b2174872d..000000000 --- a/modules/doc/application/controllers/ViewController.php +++ /dev/null @@ -1,52 +0,0 @@ -_helper->viewRenderer->setRender('view'); - } - - /** - * Populate view - * - * @param string $dir - */ - private function populateView($dir) - { - $parser = new DocParser(); - list($html, $toc) = $parser->parseDirectory($dir); - $this->view->html = $html; - $this->view->toc = $toc; - } - - public function indexAction() - { - $this->populateView(Icinga::app()->getApplicationDir('/../doc')); - } - - /** - * Provide run-time dispatching of module documentation - * - * @param string $methodName - * @param array $args - */ - public function __call($methodName, $args) - { - $moduleManager = Icinga::app()->getModuleManager(); - $moduleName = substr($methodName, 0, -6); // Strip 'Action' suffix - if ($moduleManager->hasEnabled($moduleName)) { - $this->populateView($moduleManager->getModuleDir($moduleName, '/doc')); - } else { - parent::__call($methodName, $args); - } - } -} -// @codingStandardsIgnoreEnd diff --git a/modules/doc/application/views/scripts/index/index.phtml b/modules/doc/application/views/scripts/index/index.phtml new file mode 100644 index 000000000..9be7c042a --- /dev/null +++ b/modules/doc/application/views/scripts/index/index.phtml @@ -0,0 +1,14 @@ +
+
+ +
+
+ +
+
diff --git a/modules/doc/application/views/scripts/view/view.phtml b/modules/doc/application/views/scripts/view/view.phtml deleted file mode 100644 index c9b7cb46b..000000000 --- a/modules/doc/application/views/scripts/view/view.phtml +++ /dev/null @@ -1,10 +0,0 @@ -
- -
- diff --git a/modules/doc/library/Doc/MarkdownFileIterator.php b/modules/doc/library/Doc/MarkdownFileIterator.php index cbf23ac35..e8d982ba6 100644 --- a/modules/doc/library/Doc/MarkdownFileIterator.php +++ b/modules/doc/library/Doc/MarkdownFileIterator.php @@ -6,6 +6,9 @@ namespace Icinga\Module\Doc; use \RecursiveFilterIterator; +/** + * Iterator over Markdown files recursively + */ class MarkdownFileIterator extends RecursiveFilterIterator { /** diff --git a/modules/doc/library/Doc/Parser.php b/modules/doc/library/Doc/Parser.php index c96934f7c..49f61229b 100644 --- a/modules/doc/library/Doc/Parser.php +++ b/modules/doc/library/Doc/Parser.php @@ -4,21 +4,20 @@ namespace Icinga\Module\Doc; -require_once 'vendor/Michelf/Markdown.php'; -require_once 'vendor/Michelf/MarkdownExtra.php'; +require_once 'vendor/Parsedown/Parsedown.php'; use \RecursiveIteratorIterator; use \RecursiveDirectoryIterator; use \Exception; -use Michelf\MarkdownExtra; +use \Parsedown; /** - * Markdown parser + * Parser for documentation written in Markdown */ class Parser { /** - * Retrieve table of contents and HTML converted from all markdown files in the given directory sorted by filename + * Retrieve table of contents and HTML converted from all Markdown files in the given directory sorted by filename * * @param $dir * @@ -87,7 +86,7 @@ class Parser } $fileObject->flock(LOCK_UN); } - $html = MarkdownExtra::defaultTransform(implode('', $cat)); + $html = Parsedown::instance()->parse(implode('', $cat)); return array($html, $toc); } } From 88e13c378dff75af8e69fc2480d56433eb6bc9e4 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Mon, 3 Feb 2014 15:39:53 +0100 Subject: [PATCH 03/11] Modules/Doc: Add doc display per module refs #4820 --- doc/components.md | 8 +++--- .../controllers/IndexController.php | 10 ++----- .../controllers/ModuleController.php | 11 ++++++-- .../views/scripts/index/index.phtml | 19 ++++--------- .../views/scripts/module/index.phtml | 6 ++++ .../views/scripts/module/view.phtml | 18 ++++++++++++ modules/doc/library/Doc/Controller.php | 28 +++++++++++++++++++ .../library/Doc/{Parser.php => DocParser.php} | 2 +- 8 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 modules/doc/application/views/scripts/module/index.phtml create mode 100644 modules/doc/application/views/scripts/module/view.phtml create mode 100644 modules/doc/library/Doc/Controller.php rename modules/doc/library/Doc/{Parser.php => DocParser.php} (99%) diff --git a/doc/components.md b/doc/components.md index c61ff6695..f19986d6f 100644 --- a/doc/components.md +++ b/doc/components.md @@ -29,7 +29,7 @@ A component name consists of two parts: the namespace and the name of the compon is named exactly like its JavaScript file, while the namespace is the name of the Icinga2-Web module that contains the component. Each Icinga2-Web module can contain its own components in the folder *public/js*. - / + / NOTE: The namespace used for modules defined in the Icinga2-Web core application is "app". In opposition to @@ -45,10 +45,10 @@ The full name for the component *modules/monitoring/public/js/someComponent.js* "monitoring/someComponent" -The full component name for the component *public/js/icinga/components/datetime.js* in the Icinga2-Web - core application would: +The full component name for the component *public/js/icinga/components/datetime.js* in the Icinga2-Web core application +would: - "app/datetime" + "app/datetime" ## Creating a component diff --git a/modules/doc/application/controllers/IndexController.php b/modules/doc/application/controllers/IndexController.php index d18eff5db..88834b0e1 100644 --- a/modules/doc/application/controllers/IndexController.php +++ b/modules/doc/application/controllers/IndexController.php @@ -4,20 +4,16 @@ // {{{ICINGA_LICENSE_HEADER}}} use Icinga\Application\Icinga; -use Icinga\Module\Doc\Parser as DocParser; -use Icinga\Web\Controller\ActionController; +use Icinga\Module\Doc\Controller as DocController; -class Doc_IndexController extends ActionController +class Doc_IndexController extends DocController { /** * Display the application's documentation */ public function indexAction() { - $parser = new DocParser(); - list($html, $toc) = $parser->parseDirectory(Icinga::app()->getApplicationDir('/../doc')); - $this->view->html = $html; - $this->view->toc = $toc; + $this->populateViewFromDocDirectory(Icinga::app()->getApplicationDir('/../doc')); } } // @codingStandardsIgnoreEnd diff --git a/modules/doc/application/controllers/ModuleController.php b/modules/doc/application/controllers/ModuleController.php index f59467505..dfb4ff7f9 100644 --- a/modules/doc/application/controllers/ModuleController.php +++ b/modules/doc/application/controllers/ModuleController.php @@ -4,22 +4,26 @@ // {{{ICINGA_LICENSE_HEADER}}} use Icinga\Application\Icinga; -use Icinga\Web\Controller\ActionController; +use Icinga\Module\Doc\Controller as DocController; -class Doc_ModuleController extends ActionController +class Doc_ModuleController extends DocController { /** * Display module documentations index */ public function indexAction() { + $this->view->enabledModules = Icinga::app()->getModuleManager()->listEnabledModules(); } /** * Display a module's documentation */ - public function moduleAction() + public function viewAction() { + $this->populateViewFromDocDirectory( + Icinga::app()->getModuleManager()->getModuleDir($this->getParam('name'), '/doc') + ); } /** @@ -39,6 +43,7 @@ class Doc_ModuleController extends ActionController // TODO(el): Throw a not found exception once the code has been moved to the moduleAction (see TODO above) return parent::__call($methodName, $args); } + $this->_helper->redirector->gotoSimpleAndExit('view', null, null, array('name' => $moduleName)); } } // @codingStandardsIgnoreEnd diff --git a/modules/doc/application/views/scripts/index/index.phtml b/modules/doc/application/views/scripts/index/index.phtml index 9be7c042a..a178cc155 100644 --- a/modules/doc/application/views/scripts/index/index.phtml +++ b/modules/doc/application/views/scripts/index/index.phtml @@ -1,14 +1,5 @@ -
-
- -
-
- -
-
+

Icinga 2 Documentation

+partial('module/view.phtml', 'doc', array( + 'toc' => $toc, + 'html' => $html +)); ?> \ No newline at end of file diff --git a/modules/doc/application/views/scripts/module/index.phtml b/modules/doc/application/views/scripts/module/index.phtml new file mode 100644 index 000000000..3096e4517 --- /dev/null +++ b/modules/doc/application/views/scripts/module/index.phtml @@ -0,0 +1,6 @@ +

Module documentations

+
    + +
  • + +
\ No newline at end of file diff --git a/modules/doc/application/views/scripts/module/view.phtml b/modules/doc/application/views/scripts/module/view.phtml new file mode 100644 index 000000000..7ba353e31 --- /dev/null +++ b/modules/doc/application/views/scripts/module/view.phtml @@ -0,0 +1,18 @@ + +

Module is not documented.

+ +
+
+ +
+
+ +
+
+ \ No newline at end of file diff --git a/modules/doc/library/Doc/Controller.php b/modules/doc/library/Doc/Controller.php new file mode 100644 index 000000000..da829afe1 --- /dev/null +++ b/modules/doc/library/Doc/Controller.php @@ -0,0 +1,28 @@ +view->html = null; + } else { + $parser = new DocParser(); + list($html, $toc) = $parser->parseDirectory($dir); + $this->view->html = $html; + $this->view->toc = $toc; + } + } +} \ No newline at end of file diff --git a/modules/doc/library/Doc/Parser.php b/modules/doc/library/Doc/DocParser.php similarity index 99% rename from modules/doc/library/Doc/Parser.php rename to modules/doc/library/Doc/DocParser.php index 49f61229b..fd95c053b 100644 --- a/modules/doc/library/Doc/Parser.php +++ b/modules/doc/library/Doc/DocParser.php @@ -14,7 +14,7 @@ use \Parsedown; /** * Parser for documentation written in Markdown */ -class Parser +class DocParser { /** * Retrieve table of contents and HTML converted from all Markdown files in the given directory sorted by filename From f96974fc796d825ba23b46603e1f4342313c0d0a Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Wed, 5 Feb 2014 12:35:44 +0100 Subject: [PATCH 04/11] Modules/Doc: Use Icinga\Web\Menu for the toc refs #4820 --- application/controllers/LayoutController.php | 19 +++++++ application/layouts/scripts/body.phtml | 9 ++- application/layouts/scripts/parts/menu.phtml | 28 --------- .../layouts/scripts/parts/navigation.phtml | 4 +- application/views/scripts/layout/menu.phtml | 40 +++++++++++++ .../views/scripts/module/view.phtml | 17 +++--- modules/doc/library/Doc/Controller.php | 1 + modules/doc/library/Doc/DocParser.php | 57 +++++++++++++------ modules/monitoring/{docs => doc}/instances.md | 0 .../test/how_to_test_controllers.md | 0 10 files changed, 117 insertions(+), 58 deletions(-) create mode 100644 application/controllers/LayoutController.php delete mode 100644 application/layouts/scripts/parts/menu.phtml create mode 100644 application/views/scripts/layout/menu.phtml rename modules/monitoring/{docs => doc}/instances.md (100%) rename modules/monitoring/{docs => doc}/test/how_to_test_controllers.md (100%) diff --git a/application/controllers/LayoutController.php b/application/controllers/LayoutController.php new file mode 100644 index 000000000..81bf36083 --- /dev/null +++ b/application/controllers/LayoutController.php @@ -0,0 +1,19 @@ +view->url = Url::fromRequest()->getRelativeUrl(); + $this->view->items = Menu::fromConfig()->getChildren(); + $this->view->sub = false; + } +} +// @codingStandardsIgnoreEnd diff --git a/application/layouts/scripts/body.phtml b/application/layouts/scripts/body.phtml index 24dae76ea..565a3122d 100755 --- a/application/layouts/scripts/body.phtml +++ b/application/layouts/scripts/body.phtml @@ -1,9 +1,12 @@ render('parts/topbar.phtml') ?>
- -