Search

What is a post formatter?

A post formatter is something that takes the formatter output and adds extra bits too it, an example of this would be a post formatter that adds typogrify to your HTML regardless of the initial formatter. Another example would be to add syntax highlighting to pre elements.

How do you support this?

The plan is simple, in your formatters run($string) function you add a delegate that can be used to alter the output:

  • PostFormatterHTML - For post formatters that handle HTML
  • PostFormatterXML - For post formatters that handle XML
  • PostFormatterText - For post formatters that handle plain Text

You should choose the formatter that best matches the output of your formatter. Most formatters will use HTML.

Here's an example run($string) function:

function run($string) {
    // Run your formatter here:
    ...

    // Allow post formatting:
    $this->_Parent->ExtensionManager->notifyMembers('PostFormatterHTML', '/all/', array('string' => &$string));

    return $string;
}

So, what do you think? I'm pretty sure doing this will make it a lot easier to add extra features to formatters without having to hard code it into every single one.

My opinion is biasd because i made extension because of similar reasons, so i may be wrong.

What about "PostFormatterPHP"? or "PostFormatterJavaScript"? or "PostFormatterActionScript"? or... etc... Maybe it would be better to use one "PostFormatter" delegate?

Also it will be hard to make them chained one to another, because they do not know about each other. Yeah, it's doable, but will need hacks, workarounds, etc... and if one postformatting extension wants to add something to some specific formatter, and then another wants the same, there is no way to decide which goes first (except for using names like: AAAmyformatter if they are sorted by name :).

I'm pretty sure doing this will make it a lot easier to add extra features to formatters without having to hard code it into every single one.

That's why i made Templated Text Formatters extension :).

They do fill slightly different roles, a post formatter isn't a formatter in it's own right, it just modifies a type of output: HTML, XML or Text.

Also, you could have PostFormatterJavaScript if the formatter produces JavaScript, but like I said, most formatters will produce HTML. The reason you need to have multiple delegates for post formatters is because a HTML post formatter might not be able to parse XML or Text.

Perhaps these two methods can be combined, I'll keep thinking about it :)

Update

Why don't you drop by on IRC, I need someone to bounce ideas off :P

The reason you need to have multiple delegates for post formatters is because a HTML post formatter might not be able to parse XML or Text.

I understand that, but maybe it would be better to have one "PostFormatter" delegate and provide "hint" about data type in arguments passed to it? Something like:

    $this->_Parent->ExtensionManager->notifyMembers('PostFormatter', '/all/', array('string' => &$string, 'mime' => 'text/html'));

or:

    $this->_Parent->ExtensionManager->notifyMembers('PostFormatter', '/all/', array('string' => &$string, 'mime' => 'text/plain'));

That way we can have standard types used, without a need to create hundreds of delegates.

Disadvantage: all delegates will be called each time, instead of just those for HTML. But i don't think there will be so many of them used anyway.

Advantage: it's easy to implement postformatter which works on various types of data.

Perhaps these two methods can be combined, I'll keep thinking about it :)

I can add postformatter call to templated formatters but in case of chain it's kinda hard to tell what delegate to call :). Unless i let user to decide which type of data will be generated, but then it will be limited to those 3 predefined. It would be better if user could enter any mime type :).

Update I will have more time later today (in about 7 hours), or maybe tomorrow? Which IRC server and channel? :)

Yeah, agreed, sending the mime type like that is much better. If you can then add post formatter support to TTF even better!

Personally I think the functionality provided by your extension should be part of Symphony itself, and you wouldn't select a text formatter as is, but instead roll your own.

Also, do you think you could just have the menu entries/titles say "Formatter" currently the window titles are very long :P

As for IRC, I guess tomorrow, I'll be gone in a couple of hours.

Personally I think the functionality provided by your extension should be part of Symphony itself, and you wouldn't select a text formatter as is, but instead roll your own.

Yeah, that would be great :). But installer would have to create some predefined formatters (the same way there are data-sources, components, etc... set when installing Symphony with example content).

Also, do you think you could just have the menu entries/titles say "Formatter" currently the window titles are very long :P

Hehe, i also don't like that long name in menu, but i wanted to prevent confusion in case Symphony developers decide to add own "Formatters" menu item. You can, of course, modify it - it's quite easy - just change line 35 in extension.driver.php file from:

'name' => 'Templated Text Formatters',

to:

'name' => 'Formatters',

It should still work :).

As for IRC, I guess tomorrow, I'll be gone in a couple of hours.

OK, at the same hour as our posts today?

I just thought about one more thing about postformatters - they should not call formatters, because it may create really bad recursion (server will kill script depending on timeout settings, but it's better to prevent that :).

I guess text all formatters need to specify their output mime type in their about details, so instead of typing in a mime type manually, the user is given a select box with all the available mime types. From that the correct formatters and post formatters can be chosen.

I guess this is now a feature request :)

I guess text all formatters need to specify their output mime type in their about details

Not bad idea. They could specify array of mime types they can handle, with wildcards (like: "text/*" for "any text" or simply "*" for "any"). But it shouldn't be required, so if there is no definition, it defaults to "any".

Firstly, wow, I really like this concept. But it's very ambitious - componentisation of text formatting is a tricky problem! Rowan, with your current implementation, I'm worried about:

  • future-proofing (pre-)formatters
  • avoiding the requirement that post-formatters "know about" the effects of other post-formatters registered to the same delegate
  • users may need to customise what post-formatters are effective for a given pre-formatter
  • determining order of evaluation

Turns out that we might get a chance to meet up in the next few weeks, so I'll be interested to talk to you about this if time permits. Meanwhile, here's my advice:

If/when you have access to a Mac, I want you to install SubEthaEdit and poke around with its mode API, in particular mode importing. This is used for syntax highlighting, but I believe the same principle applies to text formatting. (It allows for, say, a Javascript mode to highlight text within <script> tags of an HTML-syntax highlighted document.)

I've been thinking about how this sort of functionality could be added to the core, and specifically how to avoid the need for cooperation among formatters. I want to just make the "Text Formatter" select box multi-selectable and let the user decide which formatters will play nicely.

@ahwayakchih, your idea of using MIME types is clever. If every text formatter announced both its input and output MIME types, this would greatly assist solving the "order of evaluation" problem.

From an unordered set of selected formatters, Symphony can use these MIME types to determine if a path exists so that they can be chained, and if not, throw a warning. The only non-deterministic case is where you have multiple A->A formatters, and I believe these should, by design, work in any order.

I think there might also need to be a * (any) type, but I'm not sure whether *->* formatters should be evaluated first or last. I guess this will be decided by most common usage.

Do you think it would be worthwhile to add something like this to the core?

Scott, i didn't think of that. That's a good idea :).

The only problem is with "any" and "master/any" (like: "text/*") types order. We could make formatters let Symphony know if they should go first or last, but... i think it still would be good to let user have last word about that. I know that in theory there should not be any need for that, but in practice various formatters will have various quirks, and users don't want to wait weeks or months just to get things fixed :).

Maybe something like events are done in JavaScript? I mean first they go down from parent to deepest child node, and then back to parent - (http://www.quirksmode.org/js/events_order.html - check w3c model :)? So formatters for "any" type would go first before all others or last after all others (whichever they want, or both), but formatters for "text/*" would go first before other "text" formatters, or after them (whichever they want, or both).

To prevent calling all formatters twice, there could be RunFirst() and RunLast() functions instead of Run() (or maybe Run() and RunLast() to keep compatibility with already existing formatters :). Or maybe some kind of delegates (so we would get formatters merged with post formatter standard proposed by rowanjl).

Also, i just thought about using formatters for... images! :). There could be formatter for "image/jpg" which has settings to rescale images or some kind of a PDF2SWF formatter. So upload field could pass files to formatters and they could be automatically changed or other files could be automatically generated from them. Hmm... such files formatting would allow us to stop using image.php which currently can be used for DoS-like attacks :).

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details