Contact Us

Textile - A personal love of mine

Posted on 22/3/06 by Felix Geisendörfer

Deprecated post

The authors of this post have marked it as deprecated. This means the information displayed is most likely outdated, inaccurate, boring or a combination of all three.

Policy: We never delete deprecated posts, but they are not listed in our categories or show up in the search anymore.

Comments: You can continue to leave comments on this post, but please consult Google or our search first if you want to get an answer ; ).

Small Update: I just uploaded a picture of the Textile-powered documentation frando and me are working with which you can take a look at here.

Today I want to speak about my favourite markup, Textile. It's a very intuitive, easy to learn markup that is used to generate valid (x)html. The most awesome aspect about it is that you can stay very simple with it, but generate very complicated pages as well.

For those who don't know about it yet, just check this link here. It has sample textile which you can change and display to try out things. It also is the website of project Textpattern which was the project to invent Textile.

Well, but since then Textile has been ported to different languages (like Ruby and Perl) and cloned several times. One of those php-clones is the Textile version I'm using right now, since I think its the best one of the ones out there. It's called TextilePHP and can be found here. For questions concerning the syntax check out the documention.

If you still doubt you could create all contents of a page using textile, check out my current webdesign site, it is powered entirely by Textile and it's a pleasure to work with. Another project I'm doing a lot of Textile for is SpliceIt! or to be more exact, it's documenation. Frando and I wrote a nifty little Script that would allow us to write the entire docs in Textile but view them as Html in the browser. It even has build-in support for theming. If you are still looking for a documentation alternative feel free to take a look at it in our SVN Repository.

So but since I like to SoftHack everything I get in my fingers I found one thing that really annoyed me about textile - the fact that you can't create links that would open in a new window. So in order to make all external links automatically open in a blank window I've written a little class that adds this behavior:

class TextileHack extends Textile
     * This functions overwrites the old format_link function
     * It implements support for opening external Urls in a new window
     * @param array $args
     * @return string

    function format_link($args)
        $tag = parent::format_link($args);
        $tag = $this->__split_html_tag($tag);
        $url = $tag['options']['href'];
        // This checks if the url starts with http or ftp which would mean it's an external url!
        list($type) = explode('://', $url);
        if (in_array($type, array('http', 'ftp')))
            $tag['options']['target'] = '_blank';            

        return $this->__glue_html_tag($tag);
     * This function takes a complete (enclosed) Html Tag and splits it into it's peaces
     * This is usefull for manupulating Html Tags
     * @param string $tag
     * @return array

    function __split_html_tag($tag)
        $regex = '/\<([a-z]) ?(.*)\>(.*)\<\/[a-z]+\>/iUs';
        preg_match($regex, $tag, $matches);        

        $return['name'] = $matches[1];
        $return['innerHTML'] = $matches[3];
        $params = $matches[2];        
        $regex = '/(([a-z]+)="(.*)" ?)+/iUs';
        preg_match_all($regex, $params, $matches);  

        $params = array();
        for ($i=0; $i<count($matches[2]); $i++)
            $params[$matches[2][$i]] = $matches[3][$i];
        $return['options'] = $params;
        return  $return;    
     * This functions takes an array that was split by __split_html_tag and puts it back together
     * @param array $tag
     * @return string

    function __glue_html_tag($tag)
        $params = "";
        foreach ($tag['options'] as $key => $val)
            $params = $params.' '.$key.'="'.$val.'"';
        return '<'.$tag['name'].$params.'>'.$tag['innerHTML'].'</'.$tag['name'].'>';

I hope some people now convert to Textile as I did, because I really think it's the way to go ; ). While it might be a little bit too complicated for Joe-Average I think it's really great for sites run by people that got tired of writing Html by hand, or fidling with bad WYSIWYG-editors. It's also very nice for all of you who feel dedicated to make W3C compliant pages.

Felix Geisendörfer aka the_undefined


You can skip to the end and add a comment.

Scott  said on Mar 28, 2006:

I was just wondering what would be the easiest way if any to utilize this in a CakePHP project? It sounds really nice and I would love to start using it.

Felix Geisendörfer said on Mar 28, 2006:

Hi Scott,

I think this would be perfect for a TextileHelper which should be fairly easy to make. Just create the helper and put a uses() in there to load the Textile class out of the vendors folder.

If you need any help, let me know.

Daniel Hofstetter said on Mar 29, 2006:

There exists a textile helper on CakeForge: I don't know if it still works with the current version of CakePHP, but it shouldn't be that difficult to adapt the code.

Felix Geisendörfer said on Mar 29, 2006:

Hm, thx for the link dhofstet, I assume it's a good place to get going. But Scott, the Textile class I'm talking about above is not the "original" one. So if this helper is for the real version you are better of changing it to use the one I suggest since it has more features and less bugs ; ).

Scott  said on Apr 05, 2006:

Thanks both of you, I will see what I can come up with. If I have any problems I will let you know.

Frode Danielsen said on Apr 12, 2006:

I agree, Textile is a cool thing. But why would you want this "SoftHack"? You state a wonderful point about Textile, the fact that it can create perfectly valid XHTML - and then you want a hack which ruins this? The "target"-attribute is not allowed in XHTML 1.0 Strict (if you want Transitional or Frameset, you could just as well use HTML4). Furthermore, such choices should be up to the user imho. And even if you'd like to "force" the user into a separate window, use unobtrusive Javascript at least. And place a visual pointer for people so they may catch up on the behaviour instead of being annoyed with new windows popping up all around.

Felix Geisendörfer said on Apr 12, 2006:

Frode Danielsen:
I agree with most of what you've said. But when a client demands features and pays me well for them, then this is what I do. If I do projects for myself or for clients who care about my oppinion, I stick with the standards ; ). But opening sites in new windows is important, since it raises your chance of people staying on your site when they are finished with the one you sent them to. You have to keep in mind that most of all users are unfamiliar with tabbed browsing and rarly open things in new windows on their own ...

Peter Jacobson said on Apr 17, 2006:

I think you can address the valid code question pretty simply, just swapping out 'rel' for 'target' and 'external' for '_blank', then adding some JavaScript as in Kevin Yank's sitepoint article "New-Window Links in a Standards-Compliant World":

I'm looking forward to trying out this helper, thanks for posting.

mux  said on Oct 08, 2006:

I guess you know that TextilePHP is licensed under GPL. So, you MUST release ALL the sources of all your webapps that use it under GPL as well, that's what GNU is about.

If you want make profit and somewhat protect your customers (yeah, security through obscurity), then use Markdown licensed under BSD (and, yes, donate!).

P.s. "Errors, fill name, e-mail" message sucks. When I press back in IE, all the text disappears. It's not, well, user friendly.

Felix Geisendörfer said on Oct 09, 2006:

Uhm, I did not realize that back then. Well seems like I'll have to write my own parser one of these days - GPL sucks.

About your comment system complained: It's wordpress - you get what you pay for. I'll switch to a custom made blog application soon. But meanwhile you should consider dumping IE ...

jacmgr  said on Jan 24, 2007:

Thankx for the tip. I started using textile for documentation pages. Can;t figure out some things that maybe you already know. Are there easy way to make a link for a URL.
This works:


But would like a way to leave off the first quoted URL?

what about a cake controller/action type url

This doesn't work

"Edit This post":/post/edit/23

This works

"Edit This Post":

Do you know of an easy way to use it without fully specifying the http?

I searched, so probably not without modifying textile, byut I thought I would ask

jacmgr  said on Jan 24, 2007:

My bad..the second part is not a problem!! textile is handling those fine. Seems like my page cache was on!! Still would like to be able to type a URL and have a typed URL become a link.

Felix Geisendörfer said on Jan 27, 2007:


#1: No, I don't think you can leave off the first quoted url in Textile.
#2: No you'd definitely would need to modify Textile for this. Or, even better: Parse incomplete url's like in your example *before* you run the Textile parser over it. If you need to know how to do this, check out this paste:

It's a light weight minimalist textile helper I've written to format status messages to the User I set in the Controller of one of my applications. This should help you to get started.

Elepn said on Feb 08, 2007:


Small Business said on Mar 07, 2007:

Small Business...

all about business...

big dick sucking said on Mar 17, 2007:

big dick sucking...

abrikoskos 1092123 Reviews on big dick sucking....

This post is too old. We do not allow comments here anymore in order to fight spam. If you have real feedback or questions for the post, please contact us.