twigjs / twig.js

JS implementation of the Twig Templating Language
BSD 2-Clause "Simplified" License
1.89k stars 275 forks source link

Are globals supported? #317

Open tremby opened 8 years ago

tremby commented 8 years ago

See http://twig.sensiolabs.org/doc/advanced.html#globals

I can't find any code or wiki references.

lvl99 commented 8 years ago

+1

MichaelMackus commented 8 years ago

:+1:

JohnAlbin commented 8 years ago

(Making this issue more Google-friendly as I had a hard time finding it.)

The 3 global variables documented at http://twig.sensiolabs.org/doc/templates.html#global-variables are:

The following variables are always available in templates:

  • _self: references the current template;
  • _context: references the current context;
  • _charset: references the current charset.

Note that http://twig.sensiolabs.org/doc/deprecated.html#globals says:

  • As of Twig 2.x, the ability to register a global variable after the runtime or the extensions have been initialized is not possible anymore (but changing the value of an already registered global is possible).
  • As of Twig 1.x, using the _self global variable to get access to the current Twig_Template instance is deprecated; most usages only need the current template name, which will continue to work in Twig 2.0. In Twig 2.0, _self returns the current template name instead of the current Twig_Template instance.

[Highlighting mine.]

Since "most usages only need the current template name", I think we should do the simpler implementation where _self returns the name of the template.

tremby commented 8 years ago

Those aren't what I meant -- I'd never even heard of those. What I was referring to are user-specified global variables -- variables defined at Twig setup time which are then available to all templates no matter the context sent to the template at render time -- as documented in the link I gave.

gsouf commented 7 years ago

Without global I cannot easyly use my php twig templates in twig js. I have to inject globals every times I render a template.

gageleb commented 6 years ago

+1, is there any way to add globals in templates? for example, in php you could define {{ title}} to be whatever you wanted your title to be globally, and you wouldn't have to define title every time you rendered a template.

this is pretty important for larger projects and big templates. if this can be added, that would be cool. it's a feature in the normal twig

lvl99 commented 6 years ago

It's been a long time since I last saw this, but you could effectively write a plugin to manage your globals. Here's some dummy code which I haven't tested (i.e. don't copy and paste! Prob won't work first try):

// site-globals.js
import objectPath from "object-path"

const siteGlobals = {
  env: "development",
  config: {
    domain: "example.com"
  }
}

Twig.extendFunction("site_global", function(path, defaultValue) {
    return objectPath.get(siteGlobals, path, defaultValue)
})
{# example.html #}

{{ site_global("config.domain", "defaultvalue.com") }}

If you use Twig.js with Express, you can also initialise it with whatever variables (aka globals?) when you render the layout. Here's an example to load in the site's config data to then use in the Twig template:

// config.json
{
  "domain": "example.com"
}
// index.js
import express from 'express'
import { twig }  from 'twig'
import config from './config.json'

const app = express()
app.set('view engine', 'twig')
app.get '/', (req, res) => {
  const page = { title: "Example" }
  res.render('index', {
    // Set the data when the template is rendered as a response
    env: process.env.NODE_ENV,
    config,
    page
  })
  // You can then refer to these in the twig template like
  // {{ page.title }}, {{ env }} and {{ config.domain }}
})
app.listen(3000)
gageleb commented 6 years ago

Yeah, I'm using express now, and that's what I'm using, but in PHP's twig, you set globals in a config before the rendering process. So it would be something like

app.set('twig globals', {
    title: 'page title'
});

and then it could be referenced within the template without setting it in the object that res.render uses.

ldonis commented 6 years ago

This is the only way I can make it work, closely to the PHP implementation

// twigjs setup
twig.extendFunction('template', () => { 
    return new templateHelper() 
})

// twigjs view
{{ template().methodOfClass('text') }}

I'm using this workaround until found a better way to implement something like addGlobals

talyguryn commented 5 years ago

You can create a middleware and define global vars

/**
 * Set global vars for Twig tempates
 */
app.use((req, res, next) => {
  res.locals = {
    HOSTNAME: `${req.protocol}://${req.get('host')}`,
    TITLE: 'My amazing site'
  };
  next();
});
XiXiongMaoXiong commented 5 years ago

Yeah, I'm using express now, and that's what I'm using, but in PHP's twig, you set globals in a config before the rendering process. So it would be something like

app.set('twig globals', {
    title: 'page title'
});

and then it could be referenced within the template without setting it in the object that res.render uses.

I love you!

willrowe commented 2 years ago

Here is an updated link to the TwigPHP docs: https://twig.symfony.com/doc/2.x/advanced.html#globals