atom feed10 messages in com.googlegroups.prototype-coreRe: Template Class
FromSent OnAttachments
YaffleJun 13, 2009 9:41 am 
YaffleJun 13, 2009 12:07 pm 
YaffleJun 14, 2009 7:41 am 
AllenAug 12, 2009 5:41 am 
YaffleAug 12, 2009 11:32 am 
AllenAug 12, 2009 11:37 am 
Samuel LebeauAug 25, 2009 4:28 pm 
T.J. CrowderAug 27, 2009 2:35 am 
T.J. CrowderAug 27, 2009 3:19 am 
YaffleAug 27, 2009 3:31 am 
Subject:Re: Template Class
From:Yaffle ("vic@yandex.ru)
Date:Aug 27, 2009 3:31:21 am
List:com.googlegroups.prototype-core

My Template implementation does it too =)

In Template contrsuctor template string splits into parts and arrays of properties. Example: "<a>#{x.y}</a>" -> ["<a>",["x","y"],"</a>"] =)

I use String#split for this. ( so i use fixed cross-browser split )

On Aug 27, 4:19 pm, "T.J. Crowder" <t.@crowdersoftware.com> wrote:

Samuel,

Sorry for the "Simon" error in my last post. Years ago I knew a guy named Simon Lebeau, clearly it got ingrained my brain.

-- T.J. :-)

On Aug 27, 10:35 am, "T.J. Crowder" <t.@crowdersoftware.com> wrote:

Hi Simon,

Funny you should be doing that, I was just looking at Template the other day and thinking I might suggest a rewrite for 1.7 or 2.0.

When I did a similar thing in Java a few years back, I made it heavy on the initialization and light on evaluation -- since the point of a template is to be reused.  The idea was to turn the template string into an array of literal segments and replacement segments on init, e.g.

    "Hello #{username}, welcome to #{sitename}!"

becomes:

    Literal: "Hello "     Replace: 'username'     Literal: ", welcome to "     Replace: 'sitename'     Literal: "!"

Then evaluating the template is just running through the array; roughly (http://pastie.org/596449):

    var result, n, l, sub;     l = segments.length;     result = new Array(l);     for (n = 0; n < l; ++n) {       segment = segments[n];       if (typeof segment == 'string') {         result[n] = segment;       }       else {         sub = /* ...get substitution ... */         result[n] = sub;       }     }     return result.join('');

Your current code for #evaluate could readily be recast as the #initialize piece.

Granted this may be slightly larger (because we need to add the loop above), but it should (subject to testing) be faster.  It also lends itself to future enhancement, such as having formatting syntax, since that cost is front-loaded.  I've already proposed the first, trivial, formatter for a common use case -- a flag indicating we should escape HTML tags when
subbing:http://github.com/tjcrowder/prototype/commit/29b76e7a9e9c6168d62f1d1c...

FWIW,

-- T.J. Crowder tj / crowder software / com

On Aug 26, 12:28 am, Samuel Lebeau <samu@gmail.com> wrote:

Hi,

I've been working on a Template rewrite trying to reduce code size and   complexity. It uses `String#replace` instead of `String#gsub` and thus performs   better. Do you guys see any enhancements (in terms of performance or code   size) that could be made ?

Best, Samuel.

On 12 août 09, at 20:37, Allen wrote:

Sorry, misunderstood what you were asking. I thought you meant why can't the values be populated into the string at initialization.

On Aug 12, 2:32 pm, Yaffle <vic9@yandex.ru> wrote:

String#interpolate uses Template#evaluate. This Template realization makes some actions in constructor of Template class instead of Template#evaluate. So if you will use Template#evaluate many times for one Template object, you will save a little time.

On Aug 12, 6:41 pm, Allen <bla@gmail.com> wrote:

You should use Strings interpolate function for this. A template is meant to be reused many times with many different filler values.

On Jun 14, 10:41 am, Yaffle <vic9@yandex.ru> wrote:

var Template = Class.create({   initialize: function(template, pattern){     var parts = template.toString().split(pattern || Template.Pattern),         pl = parts.length,         pattern2 = /^([^.\[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;

    for(var i=1,k=1;i<pl;i+=4){       var before = parts[i] || '',          escaped = parts[i+1];       if(before=='\\'){         parts[k-1] += escaped;       }else{         parts[k-1] += before;

        var propList = [],             expr  = parts[i+2],             match = pattern2.exec(expr);         while(match){           propList.push( match[1].startsWith('[') ?   match[2].replace(/\ \\\\]/g, ']') : match[1] );           if(!match[3]){             break;           }           expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);           match = pattern2.exec(expr);         }

        if(propList.length){           parts[k]   = propList;           parts[k+1] = parts[i+3];           k+=2;         }else{           parts[k-1] += parts[i+3];         }

      }     }     parts.length = k;     this.parts = parts;   },   evaluate: function(object){     if(Object.isFunction(object.toTemplateReplacements)){       object = object.toTemplateReplacements();     }     object = object || '';

    var r = this.parts[0];     for(var i=1,pl=this.parts.length;i<pl;i+=2){       var propList = this.parts[i],           ctx = object;       for(var j=0,l = propList.length;j<l && ctx;j++){         ctx = ctx[propList[j]];       }       r+= String.interpret(ctx)+this.parts[i+1];     }     return r;   }});