I just got started with HTML::Mason, and upon factoring my template into smaller reusable components, I ran into something: how can the usage/existance of one aggregated component affect what went into the head section or attributes of the <body> tag? It generates output by expanding templates from top to bottom.

It reminds me of what I did a few weeks ago. I wrote some Perl code to generate SVG files for writing paper stationary (planners, note paper, etc.) and made individually coded components, much like Mason's concept. Adding a calendar to a page, for example, would generate a block of SVG as XML text to be appended to the "main" output; like the body of an HTML page. But it also adds its required stuff to a list of CSS styles and a list of defs, which go in the XML before the main content.

Those are hashes, and each component uses its own keys by prefixing the component name. So the calendar can add its styles, and if it already did so because I have more than one calendar on the page (e.g. I have 3 months along the bottom) that is redundant as it adds the same keys. Components can also inspect and modify what's already been added.

Likewise for the defs, which are individual <def> elements with everything in them that will be ref'ed by the main code. Adding the same one is redundant.

When I'm done, it generates the prelude stuff, and where the CSS goes, it combines all the items in the hash and generates one CSS style sheet embedded in the document. When it gets to the <defs> section, it lists all the collected <def> elements, in one place with no duplicates. Finally it appends the "main" code, and then the postlude.

Now with HTML::Mason, I want a component to add its CSS to that of the overall page, and likewise for script elements. The script can go in the middle of the body rather than having to be at the top, so that is less of an issue, but what if a component is used more than once on a page? I can't emit the script more than once! And putting the correct initialization in the body tag's onload attribute is a problem.

It's a different problem, but so much the same. So it occurs to me that in general as a design principle you may want to segment your output into multiple streams, and concatenate them at the end. Having a single stream them is just a special case.

Remember that when planning to generate text files, something you might do in Perl from time to time.

—John


In reply to Output should have multiple segments by John M. Dlugosz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.