On Output Format Independence

3 views
Skip to first unread message

Geoffrey Sneddon

unread,
Jan 20, 2008, 4:42:44 PM1/20/08
to habar...@googlegroups.com
One thing that has come up in the past is the issue of having Habari
force a certain Content-Type into being used. While there is little
discussion about whether this should happen in core (fun exercise: set
up a Habari blog to serve it's content as text/plain — a non-SGML-
based format — to check we don't hard-code any assumption that the
output is in a SGML-based format (and therefore uses entities, etc.)),
there was recently a long discussion about implementing widgets while
supporting multiple content-types (as this becomes difficult when
output is hard-coded). There appeared to be two main points of view in
the ensuing discussion, namely: using a plugin is a choice, if you
don't use its output format don't use it; and we must keep output
independence throughout everything.

I have major issues with the first point of view, as it will lead to
have "a" and "b", plugins both existing to create feature "x" in
Habari, while having only one difference between the two is the
output: one creates XHTML and the other HTML. I, as someone with no
clue about any programming/markup language, use plugin "b" with a
theme written by a designer for me in HTML. Plugin "b" becomes
unmaintained. I now have two choices: pay someone to maintain plugin
"b", or pay someone to convert my entire theme to XHTML. This entire
situation seems silly.

My other major issue is with the entire nature of widgets: plugin "c"
makes the naïve assumption that any time the user wants italics they
really want the emphasis something. This is hard-coded in the plugin,
and I can't do anything about it in my theme. The author of the plugin
refuses to change it ("because we like em better than i" — that's the
reaction I got from one of the main devs of Dokuwiki when pointing out
this issue, and they continued to argue blindingly they were right). I
want my _theme_ to control my output, not what I choose to use
internally (be it Habari or a plugin).

So, what would my solution to this problem be?

A plugin includes 0+ templates, each for a different output format
(say, in a "theme" folder). This template, however, can be overridden
by the currently active theme by creating a file of the same name
within a folder called "widgets" in the currently active theme. All
output handling is done through this template, so, if so desired, the
output format can be changed to the user's will without touching a
line of the plugin. This creates the intended separation of logic and
output, without using a DOM (which although a serialiser should be
used to guaranty well-formness of anything with fatal-error handling,
is very expensive to use in a language as slow as PHP; it would also
make it more complex to use output formats that can't be represented
in a DOM). This should have the effect of plugins being output-format
agnostic. As for knowing what default output to use, this means
knowing what the current output is. Attached is a sample function that
gets the current MIME type, without parameters.


--
Geoffrey Sneddon
<http://gsnedders.com/>

get_content_type.php

Owen Winkler

unread,
Jan 20, 2008, 4:53:42 PM1/20/08
to habar...@googlegroups.com
Geoffrey Sneddon wrote:
>
> A plugin includes 0+ templates, each for a different output format
> (say, in a "theme" folder). This template, however, can be overridden
> by the currently active theme by creating a file of the same name
> within a folder called "widgets" in the currently active theme.

This is currently possible.

In my in-progress plugin, Linkoid, I add a function to respond to the
"init" plugin action:

public function action_init()
{
$this->add_template('linkoid', dirname(__FILE__) . '/linkoid.php');
}

This tells the theme engine that I want to add a plugin named 'linkoid'
and that if there isn't one in the theme directory, use the one that is
in the plugin directory.

In the theme, I call <?php echo $theme->linkoid(); ?> which invokes the
following method in my plugin:

public function theme_linkoid( $theme, $tag = null )
{
if(!isset($tag)) {
$tag = Options::get('linkoid:show');
}
$linkoids = Posts::get(array('tag_slug'=>$tag,
'limit'=>Options::get('linkoid:count')));

$theme->linkoids = $linkoids;
return $theme->fetch( 'linkoid' );
}

The first few lines are related only to this plugin, but they get a list
of the last few posts tagged with a specific tag and store them in the
$linkoids variable.

The $linkoids variable is then assigned to the theme engine (via
$theme->linkoids = $linkoids;) and then the 'linkoid' theme is fetched
from the appropriate location, whether that's in the theme's directory
or the plugin's directory.

By returning the content of the processed theme, the echo statement in
the calling template outputs the processed theme.

The only difference between this and the suggested approach is that the
template is in the theme directory itself, and not in a "widgets"
subdirectory.

This functionality is in the current svn HEAD revision.

Owen


Geoffrey Sneddon

unread,
Jan 20, 2008, 4:56:30 PM1/20/08
to habar...@googlegroups.com

On 20 Jan 2008, at 21:42, Geoffrey Sneddon wrote:

> (fun exercise: set up a Habari blog to serve it's content as text/

> plain — a non-SGML-based format — to check we don't hard-code any

> assumption that the output is in a SGML-based format (and therefore
> uses entities, etc.))

To add more to this "fun" exercise: the Twitter plugin currently has
as an example:

<div id="twitterbox">
<img src="<?php echo $tweet_image_url; ?>">
<?php echo $tweet_text . ' @ ' . $tweet_time; ?>
</div>

However, this will cause issues with certain strings, e.g., "Need to
go to work&copyright my article" (and please don't turn this into a
legal discussion about copyright, I know well that this tweet is
factually wrong under the Berne Convention) would be displayed by an
HTML UA as, "Need to go to work©right my article". This is obviously
unintended. Issues with ampersands are however an issue specific to
SGML — if I use text/plain for output this is a non-issue (and I then
don't want SGML entities).

Therefore, for HTML, you'd need:

<div id="twitterbox">
<img src="<?php echo htmlspecialchars( $tweet_image_url ); ?>">
<?php echo htmlspecialchars( $tweet_text ) . ' @ ' .
htmlspecialchars( $tweet_time ); ?>
</div>

Even subtle things like this have obvious implications for different
output formats, and do very much need to be dealt with in the theme
and not in the plugin itself.

Reply all
Reply to author
Forward
0 new messages