flatiron / plates

Light-weight, logic-less, DSL-free, templates for all javascript environments!
MIT License
831 stars 69 forks source link

Multiple clauses does not render correctly #93

Open indexzero opened 11 years ago

indexzero commented 11 years ago

I've been using plates this weekend and I ran into a very strange rendering issue. Using the following HTML snippet:

<div class="page-details">
  <div class="author">
    <a href="http://github.com/github" class="github">Author Github</a>
  </div>
</div>

rendering it:

var plates = require('plates');

var map = plates.Map();

var metadata = {
  'page-details': {
    author: {
      github: 'indexzero'
    }
  }
};

map.class('page-details').use('page-details');
map.class('author').use('author');
map.class('github').use('github');
map.where('href').has(/github$/).replace(/github$/, metadata['page-details'].author.github);

console.log(plates.bind(
  [
    '<div class="page-details">',
    '  <div class="author">',
    '    <a href="http://github.com/github" class="github">Author Github</a>',
    '  </div>',
    '</div>'
  ].join('\n'),
  metadata,
  map
));

Produces the following output:

<div class="page-details">
  <div class="author">
    <a href="http://github.com/indexzero" class="indexzero">Author Github</a>
  </div>
</div>

The expected output is:

<div class="page-details">
  <div class="author">
    <a href="http://github.com/indexzero" class="github">indexzero</a>
  </div>
</div>

Basically I'm just trying to render http://github.com/github to http://github.com/indexzero and replace the innerHTML. It seems like the two clauses:

map.class('github').use('github');
map.where('href').has(/github$/).replace(/github$/, metadata['page-details'].author.github);

should do this. What am I doing wrong? Or is this a bug?

cc/ @hij1nx @3rd-Eden

indexzero commented 11 years ago

Worth noting that removing either of these two clauses does one of the two expected operations, but both will not work together.

auxsoft commented 11 years ago

I don't think this is related to multiple clauses. The bug seems to be that when there is an explicit replacement it is used in all attributes:

https://github.com/flatiron/plates/blob/master/lib/plates.js#L324

A possible solution could be:

replace https://github.com/flatiron/plates/blob/master/lib/plates.js#L316

with

if (shouldSetAttribute && mapping.replace !== key || remove || ('replacePartial1' in mapping && mapping.attribute !== key)) {

Sorry that I don't know enough about the code to make a proper patch.