[MKDoc-dev] HOWTO Add a New Document Component to MKDoc

Sam Tregar sam at tregar.com
Wed Nov 10 03:18:55 GMT 2004


I've finished the first draft of a tutorial on creating a new MKDoc
component.  Attached is an HTML copy, the POD source and four images.
Take a look and let me know what you think.  Perhaps it can be posted
on mkdoc.org somewhere?

-sam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.webarch.co.uk/pipermail/mkdoc-dev/attachments/20041109/60f5870c/mkd_component_howto.html
-------------- next part --------------
=head1 HOWTO Add a New Document Component to MKDoc

=for html
<style type="text/css">
   .illus { border: 1px dotted black; 
            margin: 5px;
            padding:3px;
          }
</style>

This HOWTO will show you how to add a new document component to MKDoc.
A document component allows editors to add content to documents and
manages the display of content to users.  For example, editors use the
HTML component to add HTML to their documents and the file component
to attach files to documents.

=head2 The Fictitious POD Component

For the purposes of illustration I'll walk through the process of
creating a POD component.  POD stands for Plain Old Documentation;
it's a markup language which is easy to write and easy to read.  I'm
writing this HOWTO in POD right now, and this section looks like:

    =head2 The Fictitious POD Component

    For the purposes of illustration I'll walk through the process of
    creating a POD component.  POD stands for Plain Old Documentation;
    it's a markup language which is easy to write and easy to read.  I'm
    writing this HOWTO in POD right now, and this section looks like:

Of course, a POD component wouldn't really make a very good addition
to MKDoc because POD is mostly used by Perl programmers writing code
documentation.  For more information about POD see:

    http://www.perlpod.com/5.8.4/pod/perlpod.html

=head2 It's Gotta Have Flo

All the code for the MKDoc component system is contained in the
C<flo/> directory inside the MKDoc root.  Why C<flo>?  Bruno Postle
told me, "Florence is Adam's fourth (I think) child, she is about four
years old and some of this code is even older."

The C<flo> system is highly object-oriented, using several layers of
inheritance to implement its functionality.  All components inherit
their functionality from the C<flo::Component> base-class.

=head2 Every Component Needs an Editor

When you create a new MKDoc Document you'll eventually end up at the
component editor screen.  Here you'll see an interface listing all the
component types available:

=for html
<div class="illus"><img src="mkd_component_howto1.png"></div>

This is actually a list of files in the C<flo/editor> directory,
reformatted to be easier to read:

    Discussion.pm
    File.pm
    Headlines.pm
    Html.pm
    Image.pm
    Link.pm
    Photo.pm
    Poll.pm
    Price.pm
    RSS.pm
    Text.pm
    TimeRange.pm

Each of these C<.pm> files implements a sub-class of C<flo::Component>
(not C<flo::Editor> as you might expect, that class does something
else).  These classes are responsible for managing both the editing of
data and the output of the data for visitors to the site.

To get started with the POD component I'll create
C<flo/editor/POD.pm>.  The easiest way to create a new editor is to
copy an existing editor and use that code as a base.  In this case I
copied C<flo/editor/Text.pm> since the POD component will be most like
Text:

    $ cp flo/editor/Text.pm flo/editor/POD.pm

After editing the C<package> line to read:

    package flo::editor::POD;

and restarting Apache, the POD component is available for adding to
documents.  However, actually attempting to add it to a document
results in an error.  That's because every editor requires a template.

=head2 Templates MK the Doc Go Round

When you add a component to a document in MKDoc the next thing you see
is an interface to edit that component.  In the case of Text that's an
HTML C<textarea> and some buttons.  This comes from a Petal template
stored in C<templates/editor>.

Just like before I'll start by copying the template for the Text
component:

   $ cp -a templates/editor/text templates/editor/pod

I used C<cp -a> because C<templates/editor/text> is actually a
directory containing a single file, C<en.html>.  If the text component
is ever translated into other languages then those files will sit
alongside C<en.html>.

To get this template ready for use I did a search-and-replace on the
copied file, changing occurrences of 'text' into 'pod'.  Of course I
was careful not to translate C<textarea> into C<podarea>!

After this work the POD component is basically functional:

=for html
<div class="illus"><img src="mkd_component_howto2.png"></div>

You can enter POD into the textarea and save to the database.  There
are two obvious problems at this stage.  First, the editing interface
doesn't have any color.  That's easily remedied by adding a class in
C<skins/admin.css>:

  .pod-component {
    color: #000;
    background-color: #9C6;
  }

Second, nothing is displaying outside the editing interface.  Users
visiting the documents aren't seeing the POD entered in the editor.
To fix this we'll need

=head2 Another Day, Another Template

Display of documents to visitors is controlled by
C<templates/document/default/en.html>.  It contains a list of
component types to loop through which will show up on the page.  To
add the POD component to this list I changed this line:

   Body_Loop             self/components_list --text --html --image
                         --photo --file --poll --discussion --headlines 
                         --rss;

To read:

   Body_Loop             self/components_list --text --html --image
                         --photo --file --poll --discussion --headlines 
                         --rss --pod;

Now the POD text shows up on rendered pages, just like text.  For
example, here's the test document I created earlier with the POD
contents "=head1 Hello World!" showing:

=for html
<div class="illus"><img src="mkd_component_howto3.png"></div>

=head2 Finally, Time to Code

Now that we've got the component working in the editor it's time to
get the output right.  Instead of just showing the raw POD entered by
the editor I'd rather show the rendered output.  I'll use
Pod::Simple::HTML from the Pod::Simple distribution
( http://search.cpan.org/~sburke/Pod-Simple/ ) to render the POD as
HTML.  Thus, the first thing to do is add a C<use> line to
C<flo/editor/POD.pm>:

   use Pod::Simple::HTML;

Then all that's needed is a new C<html()> method in
flo::editor::POD which uses the Pod::Simple API to create HTML from
POD:

    sub html {
        my $self = shift;
        my $data = $self->{'data'};

        # translate POD to HTML
        my $parser = Pod::Simple::HTML->new();
        my $output;
        $parser->output_string(\$output);
        $parser->parse_string_document($data);
        return $output;
    }

After these changes, and a quick Apache restart, the component is full
functional, turning POD formatting instructions into HTML:

=for html
<div class="illus"><img src="mkd_component_howto4.png"></div>

=head2 Further Development

That's all it takes to get a new component up and running.  However,
there's a lot more work that can be done to make components work
better.  Here are a few ideas to give you an idea of what's possible:

=over

=item *

The POD component should detect invalid POD and explain the problem to
the editor.  The way to do this is via the C<MKDoc::Ouch> API.  You
can find lots of samples of C<MKDoc::Ouch> usage in the more
complicated components like Headlines and TimeRange.

=item *

The help text in the POD editor interface needs work and should point
to a full introduction to POD.

=item *

Translating POD to HTML is a time-consuming process.  The
flo::editor::POD object should cache the translation internally so it
can be called multiple times with no additional cost.

=back

Of course, the possibilities don't end there.  MKDoc's component
system is quite flexible.  For more ideas check out the code for the
other components and their super-class, flo::Component.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: mkd_component_howto1.png
Type: image/png
Size: 7979 bytes
Desc: 
Url : http://lists.webarch.co.uk/pipermail/mkdoc-dev/attachments/20041109/60f5870c/mkd_component_howto1.png
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mkd_component_howto2.png
Type: image/png
Size: 18010 bytes
Desc: 
Url : http://lists.webarch.co.uk/pipermail/mkdoc-dev/attachments/20041109/60f5870c/mkd_component_howto2.png
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mkd_component_howto3.png
Type: image/png
Size: 8765 bytes
Desc: 
Url : http://lists.webarch.co.uk/pipermail/mkdoc-dev/attachments/20041109/60f5870c/mkd_component_howto3.png
-------------- next part --------------
A non-text attachment was scrubbed...
Name: mkd_component_howto4.png
Type: image/png
Size: 20950 bytes
Desc: 
Url : http://lists.webarch.co.uk/pipermail/mkdoc-dev/attachments/20041109/60f5870c/mkd_component_howto4.png


More information about the MKDoc-dev mailing list