Highlight code with symfony and Geshi
Symfony | PHP | Technical | Development | August 31, 2010
Sometimes when showing some code in the web, the usual IDE code highlighting is gone. That colors, which make visually different a variable from a string or maybe a reserved word. It would be great if that same visual advantage could be in our web page when using some code from a programming language.
Well, that's what GeSHI was done for. GeSHI is a generic syntax highlighter, which has support for a wide range of popular languages and has highly customisable output formats. You can download the last version of GeSHI from this url.
Once downloaded, we added it to the common lib/vendor folder in our symfony project (symfony 1.4/1.3). Because GeSHI does not follow the symfony autoloader convention we have to manually include it. Add the following line to the ProjectConfiguration.class.php file:
require_once(dirname(__FILE__).'/../lib/vendor/geshi/geshi.php');
Now suppose you have the following schema for a common post table:
Post:
tableName: post
actAs:
Sluggable: { fields: [ title ] }
Timestampable:
columns:
id: { type: integer , length: 20 , primary: true , autoincrement: true }
user_id: { type: integer , length: 20 , notnull: true }
title: { type: string , length: 200 , notnull: true }
content: { type: string , length: 20000 , notnull: true }
excerpt: { type: string , length: 500 , notnull: true }
Now add to the post form class the following methods:
protected function updateContentColumn($content) { return preg_replace_callback('#\[(\w+)\](.*?)\[/\\1\]#s', array($this, 'processCode'), $content); } protected function processCode($matches) { $geshi = new GeSHi($matches[2], $matches[1]); $geshi->set_header_type(GESHI_HEADER_PRE); $geshi->enable_classes(); return $geshi->parse_code(); }
The updateContentColumn method updates the content. At each coincidence of for example [php] .... code ..... [/php], the regular expression will extract the "php" tag and it will be assigned in the processCode method as the second parameter of the GeSHI constructor, which indicate the language to use when formatting. This way we can have a [php] ..... code ..... [/php] ...... [css] ..... some code ... [/css] ......... [python] ...... more code ....... [/python] and each differente language will be formatted according its tag.
Now, with some stylish css files like code.css:
pre { background-color : #000000; color : #FFFFFF; font-size : 14px; line-height : 1.3em; margin : 1em 0; overflow : auto; padding : 0.7em 0.7em 0; } .php .imp {font-weight: bold; color: red} .php .st_h {color: #56DB3A} .php .kw1 {color: #FF8400} .php .kw2 {color: #FFFFFF} .php .kw3 {color: #E2392D} .php .kw4 {color: #1299DA} .php .sy0 {color: #E0882F} .php .co1 {color: #B729D9; font-style: italic} .php .co2 {color: #BD48B3; font-style: italic} .php .co4 {color: #ccc; font-style: italic} .php .coMULTI {color: #BD48B3; font-style: italic} .php .es0 {color: #ddd} .php .br0 {color: #fff} .php .st0 {color: #99FF00} .php .nu0 {color: #1299DA} .php .me1 {color: #FFFFFF} .php .me2 {color: #FFFFFF} .php .re0 {color: #FFFFFF} .php a {text-decoration: none}
We can get stylish php code like the one you are seeing now.
GeSHI supports a lot of languages like php, python, css, xml, java, etc; you just have to find css classes for each of this languages to show the way you want.
In this code it is assume the use of a normal textarea to fill the data, however in a normal blog system a WYSIWIG editor is use for this purpose, like TinyMCE or FCKeditor, but when pasting some code in these editors some considerations must be taken in count. All these problems will be resolved in a future post with TinyMCE editor. For now, enjoy your new highlighted symfony code.
I recommend using the sfGeshiPlugin which is especially designed for highlighting code inside symfony projects (http://www.symfony-project.org/plugins/sfGeshiPlugin). It is well documented and should be really easy to use.