jstransformers / jstransformer-nunjucks

Nunjucks support for JSTransformers.
http://npm.im/jstransformer-nunjucks
MIT License
6 stars 6 forks source link

Function to extend the Nunjuck's Environment object #7

Closed JosefJezek closed 1 year ago

JosefJezek commented 8 years ago

Could you add option for setup env?

Like this https://www.npmjs.com/package/gulp-nunjucks-html

RobLoach commented 8 years ago

https://www.npmjs.com/package/gulp-nunjucks-html#options-setup ?

:+1:

There are a few options available during it too (filters, etc). Would love to add more.

wernerglinka commented 6 years ago

I just changed my Metalsmith build tool to the latest Metalsmith-in-place plugin. The plugin uses jstransformer and apparently I don't have to require Nunjucks in my build script anymore.

How do I set env variables like autoescape and the path to layouts with this?

I REALLY would appreciate a pointer.

slavafomin commented 6 years ago

@wernerglinka Well, actually the plugin configuration is quite simple. You can pass the directory via path config option.

And if you are interested in making Nunjucks to work with Metalsmith, I've written a small article: Making Metalsmith to work with Nunjucks.

wernerglinka commented 6 years ago

@slavafomin Thank you for your msg and the article you wrote. That gives me a pointer to follow up on.

Actually, I have been using Nunjucks for a while now with great success. I ran into a wall when I upgraded to Metalsmith-in-place v2+.

I used to require Nunjucks in my gulp file, set options and and extended the Nunjucks environment with filters. V2+ changed all that. Now I can at least set engine options.

Still have to find out how to add filters to Nunjucks ENV

MegaJ commented 6 years ago

@wernerglinka You might already know this by now, and I don't know when the feature was merged, but the feature is here I just tried this and it works with metalsmith-in-place

function shorten (str, count) {
  return str.slice(0, count || 5);
}
...
...
.use(inPlace({
        pattern: '**/*.njk',
        engineOptions: {
          path: path.join(__dirname, 'theme/layout/'),
          filters: {shorten: shorten}
        }
      }))

and my source file: {{ generatorurl | shorten(40) }}

Looks like globals is configurable too. Should the README.md get updated?

wernerglinka commented 6 years ago

@MegaJ thank you. I'll check this out ;-)

wernerglinka commented 6 years ago

@MegaJ Thanks again for responding. I ended up going back to in-place 1.x.

Now I am having another look and while in-place transforms placeholders in the content file, it doesn't apply the template. I must be doing something fundamentally wrong. I'll see if I get some help in the Metalsmith Slack channel.

wernerglinka commented 6 years ago

I found some help at the Metalsmith Slack channel. I published a repo that shows the proper use when you use Metalsmith-in-place only: https://github.com/wernerglinka/minms

wernerglinka commented 6 years ago

Could the maintainers add an option to have access the the Nunjucks environment? Filters are now accessible but extensions are not. My JS skills are limited so I might be wrong. But looking at the source code I didn't see it. I am thinking of adding extensions like Nunjucks-capture (https://www.npmjs.com/package/nunjucks-capture).

For older Metalsmith sites I have used

var nunjucks = require('nunjucks');
var CaptureTag = require('nunjucks-capture');

var env = new nunjucks.Environment();
env.addExtension('CaptureTag', new CaptureTag());

How would I do that now with jstransformer-nunjucks?

ForbesLindesay commented 6 years ago

I don't think there is currently a way to do this. Could you submit a pull request for it? You can use code similar to the filters code: https://github.com/jstransformers/jstransformer-nunjucks/blob/33ff9ddf7e30b23bd41ef1ae09c80c77f7b1bdd6/index.js#L25-L40

wernerglinka commented 6 years ago

Preliminary testing of this works:

// Add all the Extensions.
  for (const name in opts.extensions || {}) {
    if ({}.hasOwnProperty.call(opts.extensions, name)) {
      let extension = null
      switch (typeof opts.extensions[name]) {
        case 'string':
          // eslint-disable-next-line import/no-dynamic-require
          extension = require(opts.extensions[name])
          break
        case 'function':
        default:
        extension = opts.extensions[name]
          break
      }
      env.addExtension(name, extension)
    }
  }

You'd configure this like:

var CaptureTag = require("nunjucks-capture");

const templateConfig = {
    engineOptions: {
        filters: {
            toUpper: toUpper,
            spaceToDash: spaceToDash
        },
        extensions: {
            CaptureTag: new CaptureTag()
        }
    }
};
wernerglinka commented 6 years ago

@ForbesLindesay It took a while but I finally implemented this and it works. I added a PR. Could you please have a look?

RobLoach commented 6 years ago

Looks great! Merged... Mind putting together a test for it?

wernerglinka commented 6 years ago

Hi Rob, Unfortunately, I have no idea how to do that ;-( I just followed @ForbesLindesay advise and tested it on a Metalsmith site.