Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7833029
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 2, 20262026-06-02T12:32:21+00:00 2026-06-02T12:32:21+00:00

My Web application is currently using Tapestry 5.2.6. I want to write a new

  • 0

My Web application is currently using Tapestry 5.2.6. I want to write a new feature with the following requirements:

  • Users can click on items in a gallery to see a lightbox showing a detailed view, including description, comments, seller controls if they have the right credentials, and the ability to buy without leaving the page.
  • The url should be updated to reflect whether they’re in gallery view or details view.
  • URL changes should be dynamic in browsers that support HTML5 pushState. Full page refreshes are acceptable in older browsers.
  • Both the gallery page and the details page must be crawlable – users without Javascript should see a fully marked up page.
  • Speed – needs to be much faster than I know I can expect from Tapestry.

My plan is to choose and implement a template language that can evaluate equally well on the server or on the client. For the initial page load, I can render the template on the server. For subsequent updates, I can pass the item’s viewmodel object as JSON to the client and evaluate the template there.

So far so good. The problem is that none of the template languages I’ve looked at are powerful enough to feel good about moving toward for the future. As a case study, consider that out of the following:

  • Mustache
  • dust
  • Hogan
  • Handlebars

None seem to have the power to do a “wrapping” transformation like this:

# base template
{>widget}
    <span class="content">Hello world</span>
{/widget}

# widget template
<div class="widget">
    {>widget_body/}
</div>

# rendered output
<div class="widget">
    <span class="content">Hello world</span>
</div>

Notice that the wrapped content is taken from the base template, and the output of the widget template surrounds it on both sides. The only way I know to achieve this in the above languages would be a template something like:

{>open_widget/}
    {>widget_body/}
{>close_widget/}

Which means two templates for every component, an opener and a closer, both containing unclosed tags. (In fairness, dust can do this somewhat elegantly using blocks and inline partials, but because inline partials are global to the template, you’re limited to one use of the widget per template.)

My questions about templates are these:

  • I know that industry leaders like LinkedIn and Twitter are using these technologies and doing great. Am I asking too much? If you’ve used one of them, how did you deal with the “wrapping problem”?
  • A few solutions I’ve investigated do appear to support it: jquery-tmpl, which is no longer officially maintained; underscore and ejs, which make me nervous as a long term solution with their embedded code; and Closure templates. Currently Closure looks the best to me, to my surprise! If you’ve used any of these, what were your findings?
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-02T12:32:22+00:00Added an answer on June 2, 2026 at 12:32 pm

    I’m not sure whether anything out there does what you’re talking about. I needed something similar and figured writing a simple text replacement script would be quicker than comparing existing solutions and learning to use one.

    This script is not production ready (should be tested more, and the API is weird), but it should give you an idea of one way it can be done.

    Here’s how it’s set up:


    Storing templates in the document

    The template text is stored in script tags with a type attribute other than “text/javascript”. Each template has a unique id attribute.

    <script id="some_template" type="text/plain">
    
        a valid template
    
    </script>
    

    Browsers should not render these. Any characters are allowed (except </script>), and nothing needs to be escaped.


    Placeholders

    Placeholders look like this: {@some_identifier}.

    <script id="image_template" type="text/plain">
    
        <a href="{@img_url}"><img src="{@img_url}"></a>
    
    </script>
    

    Each placeholder will be replaced with either:

    • a value passed in from another template,
    • an argument passed to a JavaScript function when getting a copy of the template, or
    • an empty string if no replacement value was found.

    Including one template in another

    The @@ “pseudotag” includes the contents of another template in the current template.

    <script id="photo_template" type="text/plain">
    
        <@@ image_template></@@>
    
        <div class="photo-caption">{@caption}</div>
    
    </script>
    

    photo_template includes image_template. All inclusion replacement happens before any placeholder replacement, so photo_template has {@img_url} and {@caption} placeholders.


    Inclusion with placeholder replacement

    This is where the “wrapping” comes from. Ideally, placeholders will almost always be replaced by content from other templates, rather than values passed in when getting a copy of the template.

    <script id="missing_photo_template" type="text/plain">
    
        <@@ photo_template>
            <@ img_url>notfound.png</@>
        </@@>
    
    </script>
    

    missing_photo_template includes photo_template, providing it with a replacement for {@img_url}, so missing_photo_template has only the {@caption} placeholder.


    JavaScript

    The API sucks right now, but essentially the main namespace at has two functions, txt and node. The first one gets a copy of a template as text, the second one gets a copy as an Element (which means it should have one root node, unlike some of my examples above).

    Here it is:

    /**
    
        Atrocious Templates
    
    */
    var at = (function(){
    
      var rTemplate = /<@@\s*(.*?)>((?:[\w\W](?!<@@))*?)<\/@@>/gm,
          rOption = /<@\s*(.*?)>([\w\W]*?)<\/@>/gm,
          rValue = /\{@(.*?)\}/g,
          rTag = /<(\w+)/i,
          rSpace = /\s+/,
          templates = {},
          doc = document.implementation.createHTMLDocument('');
    
      /** 
    
          Inlcude inner templates.
    
          @private
    
          @param {string} m0
              The full inclusion text.
    
          @param {string} m1
              The ID of the included template.
    
          @param {string} m2
              Values passed to included template.
    
          @return {string} 
    
      */
      function includeTemplates(m0, m1, m2) {
        var opts = {};
        m2.replace(rOption, function(m0, m1, m2) { opts[m1] = m2; });
        return txt(m1, opts, true);
      }
    
      /** 
    
          Get text contents of a template.
    
          @private
    
          @param {string} id
              The ID of the template.
    
          @return {string} 
    
      */
      function get(id) {
        if (templates[id]) return templates[id];
        var last, t = document.getElementById(id).innerHTML;
        while (last != t && (last = t)) t = t.replace(rTemplate, includeTemplates);
        return (templates[id] = t);
      }
    
      /** 
    
          Get a text copy of a template.
    
          @param {string} id
              The ID of the template.
    
          @param {Object.<string|function ():string>} options
              Properties of this object will replace placeholder tokens.
              Each property can be either a string, or a function which 
              returns a string.
    
          @param {boolean=} noStrip
              By default, placeholders for which no replacement text is 
              found are removed. Setting this to `true` overrides that
              behavior, leaving non-replaced placeholders intact. 
    
          @return {string} 
    
      */
      function txt(id, options, noStrip) {
        if (!options) options = {};
        return get(id).replace(rValue, function(m0, m1) {
          var v = options[m1];
          return noStrip && !v && m0 || v && (v.call ? v() : v) || '';
        });
      }
    
      /** 
    
          Get a node copy of a template.
    
          @param {string} id
              The ID of the template.
    
          @param {Object.<string|function ():string>} options
              Properties of this object will replace placeholder tokens.
    
          @return {string} 
    
      */
      function node(id, options) {
        var text = txt(id, options),
            root = text.match(rTag)[1];
        doc.open; doc.write(text); doc.close();
        return doc.getElementsByTagName(root)[0];
      }
    
      // exports
    
      return { txt: txt, node: node };
    
    }());
    

    Again, I’m not recommending you use this in production as it hasn’t been tested much (although it seems to work fine), but hopefully this will give you some ideas about how what you want can be accomplished.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

we are currently working on a new web application using Java and MySql. We
Found the following snippet online and are currently using it in my web application,
I am designing a web application using GWT currently, which is also the first
Currently we're using Web Application project, so we have a gain with compilation. But
I'm currently working on web application using VB in ASP.NET. Right now I have
I am currently working on a simple web application through Google App engine using
I am using mod_perl for my web application. Currently, I plan to use a
I'm using Eclipse Ganymede to create a web application, but the project's currently just
I have a PHP based web application which is currently only using one webserver
I have a web application which currently has a bunch of users and use

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.