How to invoke custom functions in JTwig?

twig function
register twig function
drupal 8 twig functions
twig directives
twig filters
error call to a member function addextension on null in twigenvironment addextension
twig->addextension
timber functions

Is it possible to invoke custom function (say static method) from JTwig template?

For instance, in Thymeleaf framework I can call any static method via full name of its class. So I'm looking for something similar for JTwig.

This is not well documented, but here a snippet in pure Java:

final SimpleJtwigFunction myFunction = new SimpleJtwigFunction() {
            @Override
            public String name() {
                return "get_type";
            }

            @Override
            public Object execute(FunctionRequest functionRequest) {
                return "toto";
            }
        };

final EnvironmentConfiguration configuration = EnvironmentConfigurationBuilder
            .configuration()
            .functions()
                .add(myFunction)
            .and()
        .build();

final JtwigTemplate template = JtwigTemplate.classpathTemplate("hive_create_table.sql.twig", configuration);

And template:

CREATE EXTERNAL TABLE sample2(
{% for field in fields%}{% if field.name != "serialVersionUID" %}
`{{ field.name }}`:{{ field.type | get_type | upper }},{% endif %}{% endfor %}
)

This is not well documented, but here a snippet in pure Java: final SimpleJtwigFunction myFunction = new SimpleJtwigFunction() { @Override public String  How to invoke custom functions in JTwig? Is it possible to invoke custom function (say static method) from JTwig template? For instance, in Thymeleaf framework I can call any static method via full name of its class.

I've found the following solution:

1) create own function via extending org.jtwig.functions.SimpleJtwigFunction

2) register it in extended org.jtwig.environment.EnvironmentConfiguration

3) construct custom bean for the extended configuration and pass it into the JtwigViewResolver:

<bean id="jtwigDec" class="...ExtendedEnvironmentConfiguration"/>

<bean id="jtwigRenderer" class="org.jtwig.web.servlet.JtwigRenderer">
    <constructor-arg ref="jtwigDec"/> 
</bean>

<bean class="org.jtwig.spring.JtwigViewResolver">
    ...
    <property name="renderer" ref="jtwigRenderer"/>
</bean>

Building on the idea of the Twig Field Value module's filter “field_label” filter, let's call our custom function “field_respectful_label”. As outlined  ValueComparator is used for all comparisons in Jtwig. By default, the value comparator tries to convert the operands to a number (then comparing using the BigDecimal equals method) or it converts the operands to a string (using the String equals method).

i had a few problems to understand the first answer so i changed it a little...

final SimpleJtwigFunction myFunction = new SimpleJtwigFunction() {
         @Override
          public String name() {
               return "translate";
            }

        @Override
        public   Object execute(FunctionRequest request) {
            String value1 = "a Problem";
             if (request.getNumberOfArguments() == 1) {
                 if (request.get(0) instanceof String) {
                     value1 = request.getEnvironment().getValueEnvironment().getStringConverter().convert(request.get(0));
                 }
             }

            return ("This is: "+value1);
        }
    };

        final EnvironmentConfiguration configuration = EnvironmentConfigurationBuilder
            .configuration()
            .functions()
                .add(myFunction)
           .and()
      .build();


        String templatenamex = defaultpath + templatename;
        JtwigTemplate template = JtwigTemplate.classpathTemplate(templatename,configuration);
        JtwigModel model = JtwigModel.newModel();

        for (String key : map.keySet()) {
            model.with(key, map.get(key));// .replace("\"", "\\\""));
        }

        String resultx = template.render(model);

and in template

{{ translate("go") }}

creates:

this is: go

You can call all PHP functions through function() in Twig. For example, if add_filter( 'timber/twig', 'add_to_twig' ); /** * My custom Twig functionality. * * @​param  Automatically convert the keys in all maps passed to Jtwig to use strings instead of keywords. And then do this again when map values are passed by Jtwig to custom template functions and then back again when map values are returned from custom template functions.

You can define your own custom Twig functions in a custom module (but not in a theme). To find an example for how to do this, see this  How to Write a custom Twig Extension¶. Twig Extensions allow to create custom functions, filters and more to use them in your Twig templates. Before writing your own Twig extension, check if the filter/function that you need is already implemented in:

an anonymous function $filter = new \Twig\TwigFilter('rot13', function ($string) true ; Twig will pass the current environment as the first argument to the filter call: or safe, for example when adding (safe) HTML tags to originally unsafe output. In the following example, we use Jtwig in a standard Java web application. The application is packed into a war file and deployed on the NetBeans's build-in Tomcat server. In NetBeans, we create a new Maven Web Application. Figure: Jtwig servlet project structure in NetBeans. This is the project structure of the Jtwig servlet example in NetBeans.

Adding a function is similar to adding a filter. This can be done by calling the addFunction() method on the \Twig\Environment instance: $twig = new  Tag import. The import tag is the way to reuse defined macros, it affects the model, adding a variable containing all macros defined in a specific Jtwig template resource. {% import resourcePath as macros %}. As shown in the previous example, all macro definitions inside resourcePath will be stored in the macros variable, so called the alias.

Comments
  • Thanks, but I'm little bit confused about: how does it differ from what I've written in my answer? :)
  • It's a Java code, you didn't post code :p I know people love copy/paste snippet from SO, so thats why ;-)
  • your answer is appreciated, please try though not to just paste a part of code but to add some more info about it as well, so the future people reading this can easily understand what you are trying to do :)