Git Product home page Git Product logo

handlebars-helpers's Issues

helper: basename

basename

Returns the basename of a given file.

Usage:

Use {{basename}} to return the name of the current file.

or: {{basename "docs/toc.md"}}

or: {{basename [variable]}}

Generalizing code for helpers

If you are familiar with Assemble and you're reading this, then you know that we have obviously renamed "helper-lib" to handlebars-helpers.

We are not really changing anything about how helpers work with Assemble, but we will be making material changes to how helpers are packaged and organized. We will:

  • Externalize some of the utility code to a new lib/repo, probably assemble-utils
  • Organize and reduce any external dependencies
  • Add logging and error reporting to that library
  • Externalize the functions for the helpers in this repo to another repo, and then just require them back into this repo, so it might not even have a noticeable impact to current users of this lib. The reason for doing this is...
  • In the lodash-mixins repo we will require in the same functions as the handlebars helpers, which makes it more flexible so you can use either handlebars helpers or lodash mixins with the same helper methods wherever you need them.

This refactoring should also allow us to easily "templatize" the process of adding new helpers and mixins, ensuring that they are automatically added when new helper methods are added.

This "generalization" will only work with some helpers, mostly likely the helpers that can and should be generalized this way, and it also makes it clear which helpers shouldn't be included in the main libs. Any helpers that can't be generalized this way or don't seem like a good fit for the general lib will be isolated and externalized into individual repos so that they can be consumed via options: { helpers: '**/helper-*.js' }

We will add some examples and conventions for adding custom helpers to the Custom Helpers page in the documentation.

eachIndex should work with Objects too

The actual doc mentions the following:

Current implementation of the default Handlebars loop helper {{#each}} adding index (0-based index) to the loop context.

Which is not totally true, as eachIndex adds the index only for arrays, not objects.

This will work:

var data = [
  { title: "…", description: "…" },
  { title: "…", description: "…" },
  { title: "…", description: "…" }
}

{{#eachIndex data}}
  <h2>{{index}}: {{title}}</h2>
{{/eachIndex}}

This will not work:

var data = {
  firstItem: { title: "…", description: "…" },
  secondItem: { title: "…", description: "…" },
  thirdItem: { title: "…", description: "…" }
}

{{#eachIndex data}}
  <h2>{{index}}: {{title}}</h2>
{{/eachIndex}}

Maybe there is an existing solution to achieve this without altering the data source.

"Seamlessly" utilizing helper-lib in Assemble

It appears that the documentation to utilize helper-lib within Assemble is out of date since the repository shift. I'd be happy to write up the documentation, but could use some direction.

I've installed "helper-lib" via npm.

npm install helper-lib --save-dev

I then added the following line within my Gruntfile.js file.

grunt.loadNpmTasks('helper-lib');

Lastly I updated my assemble task to include the helper.

assemble: {
            options: {
                engine: 'handlebars',
                helpers: ['helper-lib', 'node_modules/assemble/lib/engines/handlebars/helpers/defaultHelpers'],
                flatten: true,
                data: 'src/data/*.json',
                partials: [ 'src/partials/**/*.hbs' ],
                assets: 'examples/assets',
                version: '<%= pkg.version %>'
            },
            ...
}

When I run any command via Grunt, I get the following error:

>> Local Npm module "helper-lib" not found. Is it installed?

When I look in node_modules I see node_modules/helper-lib, so I'm not sure what gives. If someone can give me some direction I'll make some documentation updates.

namespacing

From @Arkkimaagi on issue #33


"If the built in helpers would be found from under the _, would be a great start. The bare minimum that should be done is to help the users with collisions.

  • Better error messages (maybe that helper utility library that handles it automatically)
  • Lets check if we can detect collisions automatically and warn about them too.
  • How about listing all the variables that will be on the page scope and what they do in the docs under section "Avoiding variable name collisions" etc.

I'm thinking about a list to instruct the users about avoiding collisions using a list much like I have above. Maybe with documentation on what does what and why. Possibly a short code comment after each section and a whole paragraph after that about good guidelines to keep in mind."

namespacing

rename generic helpers to avoid collisions with local variables.

withSort does not support descending

Hi,

I'm using withSort and trying to sort by a property 'year'. But I can't choose to sort in descending order. Is there functionality to do this? Or is this something I should be adding as a custom helper?

Thanks,
Andi

helper: filename

filename

Returns the file name of a given file, including basename and extension. By default the template only requires the {{filename}} expression

An optional second parameter can be passed

Usage:

{{filename "docs/toc.md"}}

Returns:

toc.md

Of course, this probably seems useless, but when variables are used instead it would be more valuable:

{{filename snippet}}

How can I use it without node

Hi, thanks for this awesome collection of helpers.

I'm doing a project in Django, I use Backbone.js inside of the project and my javascript template renderer is Handlebars.

I need to use this helpers importing them with require.js but I don't know the way to do it, can you guide me please?

{{link}} tag causes an error

I just ran npm update on my project that was working just fine before and this problem popped to my sights.

The problem

If I have a tag named {{link}} in my handlebars code,


---
link: http://www.google.com

---
Check this out: {{link}}

Assemble throws an error:

File "index.html" assembled...ERROR
Warning: Cannot read property 'hash' of undefined Use --force to continue.

Aborted due to warnings.

If I rename this variable to something else, the compiling works just fine. I installed a clean version of assemble with grunt-init and tested by just adding the {{link}} tag to the index.hbs file.

The cause

I was able to pinpoint the line that throws this error to here:
https://github.com/assemble/handlebars-helpers/blob/master/lib/utils/utils.js#L87

This is the code on that line:

return value === 'undefined' || Utils.toString.call(value) === '[object Function]' || (value.hash != null);

And sure enough, value is undefined. I did not do a pull request related to this, as the fix looks trivial to this row. (checking if value exists before trying to access it.) But the real problem lies elsewhere.


The deeper cause

Apparently the {{link}} has been added as an helper since I last updated handlebars-helpers. Digging up why this error happened was a real pain since the error message is quite unclear. It took me a while to figure out that the {{link}} tag was the problem and a while after that to realize that there's a helper called link now. So, the problem is with the link helper. We could (and should) fix it there too. However, I think the root of the problem lies even deeper and here is a chance to talk about it.


The deeper deeper cause

Currently we have all these things in the same namespace:

  • handlebars internals (like #if)
  • handlebars-helpers (like link)
  • assemble provided variables like (pages, page...)
  • variables from grunt assemble configuration
  • user defined variables
  • user defined helpers

While the first three sources for variable names would stay in balance with each other, addition, the last three come from the user. Adding new features to any of the three first potentially breaks users variables and helpers silently. This is not a good thing.

Solution

I'd suggest that we'd have some sort of an system to handle these name collision situations and a system to avoid them. Here are my three ideas for this matter:

Idea 1

So, at first there should be a way to throw error about a variable being used as a helper when I try to define it in the frontmatter or yaml file. Also the error report about some helper failing should be way better. Maybe a try catch block around helper code somehow?

Idea 2

Then I'd recommend some sort of an way to namespace helpers, maybe with something like: Instead of naming helpers randomly, naming them instead of link to be $link or something similar. This way the helpers would not collide with user variables. I know that this is a radical change, but as the helpers library grows, more collisions will happen with already built projects and renaming variables on a single page is annoying, but doing them whole project wide, it's a pain. An alternative to this is to recommend for the user to use some naming scheme that assemble will avoid using in it's system. But that puts the load on user instead of keeping it with the tool that tries to make stuff easier for the user.

Idea 3

As a third recommendation I'd like to have a way to enable/disable builtin helpers from the grunt file. This would let the users add their modified helpers if need be to their assemble projects with same name, or fix problems that happen on namespace collisions. Maybe a configuration to blacklist/whitelist helpers would be nice. So that I could choose if I want to remove some of the builtin helpers with a blacklist and keep all the rest (and future upcoming ones), or if I want to include only select few helpers by whitelisting them and ignore all the rest (even future ones).

eachIndex+1?

How about a eachIndex helper that has 1 based indexing instead of 0 based?

label helpers to indicate how they should be sorted

once we implement a system for wrapping the helpers, most of the helpers in the lib will work with any env right out of the box. however, some of them won't. A small handful of the helpers are pretty much hard-coded to either node.js, assemble or grunt.

We need to get those helpers sorted out or labeled somehow so we can automate the process for wrapping all the helpers at once

Get page variable in nested block helpers

Someone discovered an issue with the i18n task that I'm trying to resolve. Given the current code:

{{#prettify}}
  {{#i18n "key"}}{{/i18n}}
{{/prettify}}

The i18n fails because it no longer sees the language parameter of the page. I'm wondering, how do I get access to the page regardless of where the block is.

embed helper: {{ embed [filename] [syntax] }}

embed

For embedding code snippets by referencing an external file.

Embed code snippets from any file/accepted file types with the embed variable. You can also pass in a second parameter to force syntax highlighting for a specific language.

Parameters: String|String (optional)
Default: undefined
Syntax: {{ embed [filename] [syntax] }}

Example:

{{ embed 'src/test.json' }}

Forced highlighting: in this example highlighting is forced as javascript instead of json.

{{ embed 'src/test.json' 'javascript' }}

"usemin" helper

Every time I see grunt usemin in a project it makes me cringe. This would be so much easier to do with Assemble and helpers.

helper: blockquote

blockquote

Create a blockquote

Outputs a string with a given attribution as a quote.

{{#blockquote "doowb" "http://github.com/quote/source" "This is the title" }}
  This is your quote.
{{/blockquote}}

results in:

<blockquote>
  <p>This is your quote.</p>
  <footer> 
    <strong>`doowb</strong>
    <cite> 
      <a href="http://github.com/quote/source">This is the title</a>
    </cite>
  </footer>
</blockquote>

helper: gist

gist

Embed Gists

  • {{ gist 519323 }}
  • {{ gist 5193239 file1.md }}

Embed public GitHub Gists by adding only the Id of the Gist. The helper also accepts an optional second parameter for targeting a specific file on the Gist.

Parameters: String|String (optional)
Default: undefined
Syntax: {{ gist [id] [filename] }}

Example:

{{ gist 5193239 }}

You can pass in a file name as a second parameter if you need to embed multiple files from the same Gist, like this:

{{ gist 5193239 file1.md }}
{{ gist 5193239 file2.md }}
{{ gist 5193239 file3.md }}

Suggestion: valueIn helper

How about an inverse of the {{inArray}} helper? Something that would work like the example docs below.

If there's enough interest in this I'd be glad to submit a pull request and make it so. If I do so, which section should it go into? (Collections?)


{{valueIn}}

Conditionally render a block if the value is in a specified collection.
Parameters: value string|int - One or more values to test against. (Required), [...]

Data:

"value": "Fry"

Template:

{{#valueIn value "Professor Farnsworth" "Fry" "Bender"}}
  I'm walking on sunshine!
{{else}}
  I'm walking on darkness.
{{/valueIn}}

Renders to:

I'm walking on sunshine!

eachProperty does not work properly

First of all, the documentation on the README.md says that one can use the eachProperty like this:

{{#eachProperty object}}
    {{property}}: {{value}}<br/>
{{/eachProperty }}

(The documentation on this part seems to be under construction, as some parts of it are totally missing.)

While in the code it's returned like this:

result += options.fn({
  key: key,
  value: value
});

Which means that the documentation should be updated to:

{{#eachProperty object}}
    {{key}}: {{value}}<br/>
{{/eachProperty}}

Or the returning thing should be changed to "property" like in the docs.

The code however still does not work, as whenever I try to use {{value}} inside handlebars code, I get this error:

Warning: Unable to read "[object Object]" file (Error code: ENOENT). Use --force to continue.

If I access the same variable by {{lowercase value}} it works as expected.

I tried to find colliding helpers and such, but I was unable to do so.

helper: {{ include }}

Works like partials, but allows you to use variables:

---
layout: default.hbs
title: Some Page Title
content: ../path/to/my_content.md

---

{{{ include content }}}

{{{ include "some-partial.md" }}}

and it would be great to be able to pass in an optional third parameter for data to override the default data that would be used for a template: {{{ include [partial] [data] }}}

{{{ include "some-other-partial.hbs" "path/to/data.json" }}}

formatDate formats timezone incorrectly

I tried to dig to the original library, but it is gone and links mentioned in docs nolonger work.

This helper is a port of the formatDate-js library by Michael Baldry.

if I render time with moment.js like this:

moment().format("ddd, DD MMM YYYY HH:mm:ss ZZ")

I get:

Sat, 29 Jun 2013 23:40:08 +0300

If I render with formatDate I get with this:

---
lastBuildDate: <%= new Date() %>

---
{{formatDate lastBuildDate "%a, %d %b %Y %H:%M:%S %z"}}

this result:

Sat, 29 Jun 2013 23:40:08 +0003

Notice how 3 hour timezone has changed to 3 minute timezone? Not good. 👎

What if we'd use moment.js instead and get bunch more options with it? Sure, the old formattings would break, but..

Generating a navigation with dynamic active class

I'm trying to generate a navigation with a dynamic active class & here is my YAML & Handelbars

config.yaml


---
mainnav:
- home
- about us
- contact

---

menu.hbs partial

{{#config.mainnav}}
      <li><a {{#is page.basename this}} class="is-current" {{/is}} href="{{hyphenate this}}.html">{{capitalizeEach this}}</a></li>
{{/config.mainnav}}

everything is working but the active class, it doesn't get applied at all.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.