Baking with Markdown and dp.SyntaxHighlighter

By Hannibal Lecter aka "lecterror"
Creating a content editor with has never been easier. All you need is Markdown and dp.SyntaxHighlighter!
After a brief discussion on CakePHP group, I've decided to try - as John Cleese would say - something completely different. That is, I've decided to try to use a markup language instead of WYSIWYG. I was using TinyMCE for a while, and I suppose it's OK for an uneducated end user and a "standard" CMS.

But since Neutrino is going to be a CMS for developers (the project I'm working on privately), that's just not good enough.

My first choice for a markup language was Markdown (http://daringfireball.net/projects/markdown/). But then I saw something called "Markdown extra" (http://michelf.com/projects/php-markdown/) and decided to go with that. Turned out to be a good choice.

Integrating Markdown with CakePHP was in fact a piece of Cake, with just a few simple steps.

  • Download Markdown extra and put it in /app/vendors/markdown
  • Create a Markdown helper

Helper Class:

Download code <?php 
vendor
('markdown'.DS.'markdown');

class 
MarkdownHelper extends AppHelper {
    function 
parse($text) {
        return 
$this->output(Markdown($text));
    }
}
?>


  • Make sure you put it in your controller


Controller Class:

Download code <?php var $helpers = array('Markdown');?>

  • Use it in your view


View Template:

Download code <?php
echo $markdown->parse($article['Article']['content']);
?>


All you need to do now is learn Markdown (http://daringfireball.net/projects/markdown/syntax) and some Markdown extra stuff (http://michelf.com/projects/php-markdown/extra/) :-)

What about syntax highlighting?



My main problem while using WYSIWYG editors was to preserve code formatting. Which was impossible. With no respect to tricks and all kinds of plugins and black magic, the code would always end up in a mess.

Now that's no problem. The only problem now is handling the tab key inside a textarea. Luckily, after googling for a while, I was able to combine a solution that actually works:

Download code
// /app/webroot/js/tabulator.js
function insertTab(event, obj)
{
    var tabKeyCode = 9;
    if (event.which) // mozilla
        var keycode = event.which;
    else // ie
        var keycode = event.keyCode;

    if (keycode == tabKeyCode)
    {
        if (event.type == "keydown")
        {
            var oldscroll = obj.scrollTop;

            if (obj.setSelectionRange)
            {
                // mozilla
                var s = obj.selectionStart;
                var e = obj.selectionEnd;
                obj.value = obj.value.substring(0, s) + "\t" + obj.value.substr(e);
                obj.setSelectionRange(s + 1, s + 1);
                obj.focus();
            }
            else if (obj.createTextRange)
            {
                // ie
                document.selection.createRange().text = "\t"
                obj.onblur = function() { this.focus(); this.onblur = null; };
            }

            obj.scrollTop = oldscroll;
        }

        if (event.returnValue) // ie ?
            event.returnValue = false;
        if (event.preventDefault) // dom
            event.preventDefault();
        return false; // should work in all browsers
    }
    return true;
}


Include the script in your layout:

View Template:

Download code <?php
// /app/views/layouts/default.ctp
echo $javascript->link(array('tabulator'));
?>


And you just attach it to your textarea:

View Template:

Download code <?php
echo $form->input(
    
'Article.content',
    array(
        
'onkeydown' => 'insertTab(event, this);'
    
));
?>


So now we have the tab working, all that is left is highlighting itself with dp.SyntaxHighlighter (http://code.google.com/p/syntaxhighlighter/). We accomplish that fairly easily.

  • First, download the highlighter from the address above
  • Deploy the brushes in /app/webroot/js/dp.SyntaxHighlighter
  • Deploy the CSS in /app/webroot/css/


Now add them to your layout just as before:

View Template:

Download code <?php
echo $html->css('SyntaxHighlighter');

echo 
$javascript->link(
    array(
        
'tabulator',
        
'dp.SyntaxHighlighter/Scripts/shCore',
        
'dp.SyntaxHighlighter/Scripts/shBrushPhp',
        
// additional brushes as needed
    
));
?>


The only thing left is to actually tell dp.SH to highlight the code. You do this at the end of your layout, just before you close the <body> tag.

View Template:

Download code <?php
echo $javascript->codeBlock(
    
'dp.SyntaxHighlighter.HighlightAll("code_snippet");'
    
);
?>


So how does it work anyway?



Fairly easy. You just type this into your textarea:

Download code <pre name="code_snippet" class="php:nocontrols:nogutter">
    // hello
    echo 'Arthur "Two Sheds" Jackson';
    // go away
</pre>


and after markup and dp.SH it should turn into a nice block of highlighter code. If curious, you can go to the original location of this article to see it in action (http://dsi.vozibrale.com/articles/view/baking-with-markdown-and-dp-syntaxhighlighter)

You're ready to go, with one textarea, one tiny helper and a lot of 3rd party code. Total time to accomplish this: 15 minutes (coffee break included:-))

Happy baking!

Comments 616

CakePHP team comments Author comments

Comment

1 wysiwyg editor for markdown syntax

You could find a wysiwyg editor for markdown syntax here:
http://sourceforge.net/projects/md-wysiwyg/

I believe there's someone also need this. :)
posted Mon, Feb 18th 2008, 19:13 by Finjon Kiang

Login to Submit a Comment