On Mon, May 23, 2005 at 06:37:55PM -0700, Steve Kelem wrote:
> I'm building a hierarchy of web pages.
> Is there a way, in the template toolkit, to make references/links to
> places in web pages somewhere in the hierarchy without knowing exactly
> where they are, knowing just the name of the link?  I'd like to avoid 
> having to know exactly where in the hierarchy the target of a link is, 
> sort of how the xml map works.

I use a modified version of the site map described in chapter 11 of
the Badger book (~p 423) to define the layout of pages.

Then I have a macro:

   MACRO link_to_page(target, text, return_link_only ) INCLUDE 
menu/find_menu_link;

that walks the map looking for the link.  And in a template I do:

   Read [% link_to_page('install#tips', 'these important tips') %]

Which allows custom text, or:

    Please see the [% link_to_page( 'foo' ) %] page.

which uses the text in the map.


There's a few pending TODO, but here's the macro.
Corrections/suggestions are alwasy welcome...


:r menu/find_menu_link


[%
    # Macro passes in 
    #   "target"            a menu id in config/map
    #   "text"              optional text to use instead of link text
    #   "return_link_only   optional flag to say return only the href
    # Link text is NOT html escaped.  Href is also not correctly escaped.
    # Note that there's nothing to prevent a map/menu from having two menu items
    # at different levels from having the same id.  Therefore, this processes 
each
    # menu level before recursing, so it should find top level ids first.

    # TODO
    # - allow passing in a tooltip (title)
    # - set class attribute saying if internal or external link.


    SET global.link_found = 0;  # to track when found so can stop recursing


    SET fragment    = target.replace('^[^#]+','');
    SET target_id   = target.replace('#.+$','');

    link = INCLUDE look_for_link;

    THROW 'menu', "Failed to find menu link for target '$target_id' from page 
$template.name"
        UNLESS link;
    link;
-%]
[%- BLOCK look_for_link;

    # Finds an entry in the site map. Call with the link_to_page(id) macro
    # TODO - make abort if not found

    subdirs = [];

    FOREACH id = map.page.keys;
        item = map.page.$id;

        # Is there a sub menu that should be looked through later?
        subdirs.push( item ) IF item.page;

        # Is this the item we are looking for?
        NEXT UNLESS id == target_id;

        global.link_found = 1;

        SET href = "${item.url}$fragment";

        IF return_link_only;
            href;
            RETURN;
        END;

        "<a href=\"$href\"";
        " title=\"${item.tooltip}\"" IF item.tooltip;
        ">";
        text || item.name;
        "</a>";


        RETURN;
    END;


    FOREACH item = subdirs;
        LAST IF global.link_found;
        INCLUDE look_for_link map = item;
    END;

END -%]

-- 
Bill Moseley
[EMAIL PROTECTED]


_______________________________________________
templates mailing list
[email protected]
http://lists.template-toolkit.org/mailman/listinfo/templates

Reply via email to