assemble / assemble.io

Website and documentation for Assemble.

Home Page:http://assemble.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

undefined properties

waynedpj opened this issue · comments

i am trying to update the docs on partials and the Assembler helpers available. however, when i use the partial helper as below:

{{partial 'img'}}

in the Partials.md.hbs page, the following error occurs:

Warning: An error occurred while processinsdfg a template (Cannot read property 'title' of undefined). Use --force to continue.

it seems like the use of the partial helper is triggering the evaluation of some undefined properties inside LoDash templates, specifically in the following files:

the problem seems to be the lines like <%= some.title.variable %> and <%= some.author.variable %>. while i can define them in YFM to make Assemble happy, is there a way to tell Assemble to not parse these examples for LoDash, similar to how we currently prevent Handlebars from evaluation examples in the docs via \{{something}}? i have yet found a way to do this easily in the templates (i.e. no programmatically).

thanks.

This section of code in the partial helper might be causing the issue. It looks like the this variable might have either some of the markdown from the wrapping block expression or might have something else in it that is causing the grunt.config.process method to try to parse it with lodash.

I don't see the Partials.md.hbs page that you're referring to. Do you have a link to it?

Also, I'm not aware of a way to escape the lodash templates like you can in Handlebars. They have an escape delimiter but that's supposed to escape variables that might have html in them.

This section of code in the partial helper might be causing the issue. It looks like the this variable might have either some of the markdown from the wrapping block expression or might have something else in it that is causing the grunt.config.process method to try to parse it with lodash.

thanks for the pointer: removing both the this and opts arguments from this line allowed the build to finish but i imagine this is not the final fix, even though my simple use of the {{partial}} helper seems to be working fine. i will play around a bit more then post an issue for the helper since that seems to be the cause of Markdown getting pulled into the template evaluation.

I don't see the Partials.md.hbs page that you're referring to. Do you have a link to it?

sorry, it is now in my local repo fork of the docs here. i had not yet pushed it as i have been struggling to get the docs built without --force and local hacks due to this problem and this issue with the helper. i will hold off on doing a PR for this doc update until these 2 issues are fixed as it will not build currently.

note that this also error also occurs with the currently published Partials.md.hbs simply by adding {{partial img}} to the page, so i do not believe it has anything to do with my updated Partials.md.hbs.

also, thanks for confirming about escaping LoDash templates, it is what i have found as well.

simply by adding {{partial img}}

So, to clarify, do you want {{partial 'img'}} to be evaluated? If not, you need to escape it, like \{{partial 'img'}}. But If so, did you do npm i handlebars-helper-partial first? That helper has to be installed since it's not part of the handlebars-helpers lib.

So, to clarify, do you want {{partial 'img'}} to be evaluated?

both ;) since i have an example using the {{partial 'img'}} helper in the updated docs, i have it both escaped to show usage and non-escaped to show output.

also, i created the img.hbs partial in the right place (using it via {{> img}} works), installed the helper via npm (it is being invoked), etc.. the problem is that the helper is failing due to the 2 issues mentioned above which both seem related to the helper itself and not the docs.

the problem is that the helper is failing due to the 2 issues mentioned above which both seem related to the helper itself and not the docs.

Lol seemingly, but I'm not sure I agree yet. You may be correct, but my gut tells me it's something else having dealt with similar issues so many times. Taking out this and opts will break lots of other code, as those contexts are required elsewhere. Of course, if we keep stripping code out the error messages might go away, but that doesn't mean it's actually solving the problem.

Try using a longer, more descriptive name for the partial, like {{partial 'img-example'}}. It sounds like there is already an img partial registered.

Lol seemingly, but I'm not sure I agree yet. You may be correct, but my gut tells me it's something else having dealt with similar issues so many times. Taking out this and opts will break lots of other code, as those contexts are required elsewhere. Of course, if we keep stripping code out the error messages might go away, but that doesn't mean it's actually solving the problem.

i definitely agree and i never meant to imply that my "fixes" where anything but temporary hacks. i just mentioned them in a effort to help debug the problem, not as a potential PR ;)

Try using a longer, more descriptive name for the partial, like {{partial 'img-example'}}. It sounds like there is already an img partial registered.

that is a good idea, apologies for not trying that earlier. unfortunately renaming the partial to various things, including img-example.hbs and ABCXWY.hbs, did not prevent the error.

unfortunately renaming the partial to various things, including img-example.hbs and ABCXWY.hbs, did not prevent the error.

Hmmm, that's strange. Thanks for checking. What is the content of the partial, can you paste that up here? Also, is the partial helper working anywhere else in the docs? If not, are you sure it's registered properly? (we need to do better regarding error messages with helpers and plugins).

What is the content of the partial

img.hbs

---
class: image
---
<img src="{{assets}}/images/{{URL}}"
     class="{{#each classes}}{{this}} {{/each}}{{class}}"
     id="{{#if id}}{{id}}{{else}}{{slugify title}}{{/if}}"
     width="{{width}}"
     height="{{height}}"
     title="{{title}}"
     alt="{{#if alt}}{{alt}}{{else}}{{title}}{{/if}}"/>

also available here

Also, is the partial helper working anywhere else in the docs?

when i add the {{partial 'img'}} helper to other pages it is definitely getting called. however, it fails with the same error message about the undefined property. it seems like using this helper results in the context mistakenly getting some page content which includes Markdown that has an example LoDash template <%= some.title.variable %> in it. thus, the helper tries to resolve the template during the grunt.config.process call and fails with Warning: An error occurred while processing a template (Cannot read property 'title' of undefined)..

also, using the img.hbs partial via {{> img}} works as expected.

I found 3 templates that contain lodash templates in their body referencing title:

  • Data.md.hbs
  • FAQ.md.hbs
  • YAML-front-matter.md.hbs

When I exclude them from the build, I get a new error:

image

This is happening during the grunt.config.process method after all the contexts are merged: context = _.extend({}, grunt.config.data, opts, this, opts.data[name], metadata, context);

Since that contains the entire context from assemble and assemble is storing the html for all the pages, grunt tries to process the entire page value though lodash. I'm not sure how to get around this since the whole point of using the partial helper is to get the contexts merged together.

Then instead of removing this and opts, it should probably just _.omit the page property and/or whatever properties contain the full content of the page. That seem like it would work?

Yep... using _.omit on opts and this and removing pages and pagination does the trick. Also, the fix that @waynedpj submitted to check if the partial is a function is required for it to work.

It would be nice if there was just a way to escape lodash templates, but then I think it would show up that way in the example code.

great! yeah I agree about escaping lodash templates. Here is what I did in grunt-readme: https://github.com/assemble/grunt-readme/blob/master/tasks/lib/utils.js#L114-L121

@doowb, this might be a good use case for externalizing the logic used in merging the context. maybe we should publish a lib that has a parameter for an options object that can define which contexts to merge in. This logic should be reusable with any helper that is used with assemble.

this might be a good use case for externalizing the logic used in merging the context.

i was actually going to ask about the same thing: as i have started to investigate the code of various helpers/plugins to learn how Assemble works/how to write a plugin/helper, i have noticed various bits of repeated modules that may be useful as a lib.

in particular i am looking at how data is merged into the context and thus far i have found various methods depending on the type of data:

maybe these methods would be good for a starting point. not that you 2 are not busy enough, just wanted to give a 👍 to the the idea and help where i can once i have a go at a plugin.

also, thanks for finding this bug in the partial/include helpers. once the fixes are live in handlebars-helper-partial i will make a PR on the partial doc update. should i make a new issue at that repo for this new bug?

peace

Awesome! @waynedpj thanks this is really helpful! I think there are actually like 8 or 9 different "levels" of context (the fact that I'm not sure just emphasizes the point that a dedicated lib would be usedful!). The tricky part is that depending on the use case, at least 3 or 4 of the contexts should merge in different orders. So the lib you mentioned should expose an API that gives devs the ability to define the order in which they are merged.

should i make a new issue at that repo for this new bug?

That might be a good idea, on the issues for that helper. thanks a lot!

@doowb did i summarize the solution correctly -> helpers/handlebars-helper-partial#3 ?

if so, i could make another PR with this seemingly simple fix.

So the lib you mentioned should expose an API that gives devs the ability to define the order in which they are merged.

@jonschlinkert OK, i am seeing this a bit more as i delve deeper. i have a few util functions already that could be part of this Assemble lib but i still do not have a good understanding of the entire context parts so it will take some time. and thank you 2 for Assemble, this is the least i can do :)

Looks good. I just merged your other PR that fixes the partial as a function issue. When this PR is sent, I'll merge and bump the version.

@waynedpj thanks for the contributions and help us figure these issues out.

@doowb my pleasure .. thank you both for Assemble and your patience with my questions!!

i made the PR but it could prob use a test case (e.g. simply having a LoDash template in some page content that references a undefined property). unfortunately i am unsure yet how your tests are built.

Most of our tests involve having fixture templates that contain the issues that we run into. We run against those templates to make sure it's working. That's what I did with your assemble-docs repo that was causing the issue.

I bumped the version and published the changes. I'm going to close this now since the issue should be resolved. Reopen if you think there's still something else missing.

Thanks again.

Most of our tests involve having fixture templates that contain the issues that we run into. We run against those templates to make sure it's working.

OK, i will take a closer look. i had just assumed that there was some JavaScript code and testing framework involved and thus more complicated than that.