The simplest possible CMS with CMarkdown and Yii
Well saying “CMS” means a huge over-interpretation here. This article shows how to actually write the quickest and the simplest possible rich-text page content render for rendering Markdown-formatted texts stored in separate .txt
files.
The entire article is actually a single Yii action plus an example on how to call it.
This solution uses CFile extension. More information about Markdown formatting, used here, can be found at this page or in Yii doc for CMarkdown
class.
This solution assumes following:
- texts are formatted using Markdown and are stored in separate files,
- each file contains page’s title in the first line and actual content in remaining lines,
- files has fixed path (
files/pages/
), where they’re stored, and fixed extension (.txt
).
To render Markdown-formatted texts stored in separate class I’m using this simple action:
/** * This is the default 'index' action that is invoked when an action is not * explicitly requested by users. It is also used to display texts form external * files with (or without) Markdown formatting. * * This function uses CFile extension (http://www.yiiframework.com/extension/cfile). * * More information on Markdown-style text formatting can be found under this * address: http://daringfireball.net/projects/markdown/syntax or in Yii doc * about CMarkdown class: http://www.yiiframework.com/doc/api/1.1/CMarkdown/. * * @param string $page Page name, here transformed to full filename. * @param boolean $withMarkdown Whether to show contents "as-is", without Markdownformatting. * * @throws CHttpException A standard exception, if given page does not exits. */ public function actionIndex($page = '', $withMarkdown = true) { if($page !== '') { $filename = 'files/pages/'.$page.'.txt'; $file = Yii::app()->file->set($filename); if($file->exists) { $data = explode("n", $file->getContents()); $title = array_shift($data); $body = implode("n", $data); if($withMarkdown === true) { $markdown = new CMarkdown; $contents = $markdown->transform($body); } else $contents = $body; $this->render('page', array ( 'title' => $title, 'contents' => $contents )); } else throw new CHttpException(404, 'Invalid request. Please do not repeat this request again.'); } else $this->render('index'); }
Actions arguments are:
- a valid path to
.txt
file (required). - disable Markdown formatting; enabled by default (optional).
When everything is OK, this action reads contents of $page
file and renders it using CMarkdown
class. Action throws standard CHttpException
exception, if given page (file) does not exits.
Above action generates following variables:
- markdown formatting result (returned by
CMarkdown::transform
method) is fetched to$contents
variable, - page’s title is fetched to
$title
variable
and thus my view file for above action can be as simple as:
<?php /* @var $this MainController */ $this->pageTitle = Yii::app()->name.' - '.$title; $this->breadcrumbs = array($title); ?> <?php echo($contents); ?>
The last line one can be of course also written in simpler form as:
<? $contents; ?>
Some details:
index
action is default one in myMainController
,- I have URL-rewriting in Yii set to use “pretty” URLs,
- I’m using
.html
suffix in the end of each URL,
I can render each of my info-like pages with URLs as simple (and “pretty”) as:
http://www.example.com/main/about.html
Where about
refers to /files/pages/about.txt
file in my application’s main folder.
You may be interested in reading this blog post as well. It discussed problem of writing correct (for Yii) links in external Markdown-formatted text files, as shown in current article.