Git Product home page Git Product logo

twig-html-loader's People

Contributors

dependabot[bot] avatar kostik-noir avatar olets avatar pierreburel avatar radiocity avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

twig-html-loader's Issues

Nested namespaces

What if I have something like Something:folder1:file.html.twig how can I add that to the namespaces?

Relative base views folder

Directory setup:

| partials
| --header.html
| --header.html
| layouts
| --base.html

Is there a way to write {% include "partials/header.html" %} inside my base.html file without having to do {% include "./../partials/header.html" %}

gulp-twig has a base option to set extends/includes relative to the defined option

TwigException: include function does not exist and is not defined in the context

hi,

the loader :

const twig = {
  test: /\.twig$/,
  use: [
    'raw-loader',
    {
      loader: 'twig-html-loader',
      options: {
        data: context => {
          const data = path.join(__dirname, 'data.json');
          context.addDependency(data); // Force webpack to watch file
          return context.fs.readJsonSync(data, {throws: false}) || {};
        },
      },
    },
  ],
};

used with :

const generateHTMLPlugins = () =>
  glob.sync('./src/pages/**/*.twig').map(dir => {
    const filename = path.basename(dir);

    return new HTMLWebpackPlugin({
      filename: filename.replace('twig', 'html'),
      template: path.join(config.root, config.paths.src + '/pages', filename),
    });
  });

and the templage :

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    {{ include('../partials/header.twig') }}

  </body>
</html>

thanks in advance for your help!

Data not working as intended?

Hey there,

I'm not sure if I'm trying to use data option correctly or not but I'm running into some issues. I've been following the readme and I'm using data as this right now:

const data = path.join(contextPath, `${name}.json`);
context.addDependency(data); // Force webpack to watch file
return context.fs.readJsonSync(data, { throws: false }) || {};

This seems to work properly since I get the correctly rendered html string inside my webpack bundle. However, I can not use this for including a .twig file into my index.twig.

Using {% include '@components[name].twig' %} works but it only includes the plain .twig file without its corresponding data. These are not known to any .twig file. Only webpack knows about that. Yet I still couldn't figure out a way to get the string out of my webpack bundle and use it in my rendered index.html.

Am I missing something here? Or is this an intended behaviour? I'd really like to get my rendered templates into my index.html.

Error then using async function and filters

Then I try to add async function, for example:

functions:{
   getFileInfo:(value,...args)=>{
      return new Promise((resolve,reject)=>{
          setTimeout(()=>{
              // get file info from DB
               return resolve(JSON.stringify(require("./demo_data/file_data.js")))//info about file
            },3000)
       })//promise
   },//getFileInfo
}

I got error:

NonErrorEmittedError: (Emitted value instead of an instance of Error) TwigException: You are using Twig.js in sync mode in combination with async extensions.

Included partials are not being refreshed.

Hello, my structure looks like:
index.html
-_partials/footer.twig

webpack.config.common.js:

const glob = require('glob');
const path = require('path');

const CopyWebpackPlugin = require('copy-webpack-plugin');
const HTMLWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

const options = require('./src/options');

const generateHTMLPlugins = () =>
  glob.sync('./src/**/*.html').map(
    dir =>
      new HTMLWebpackPlugin({
        filename: path.basename(dir), // Output
        template: dir, // Input
      }),
  );

module.exports = {
  node: {
    fs: 'empty',
  },
  entry: ['./src/js/app.js', './src/style/main.scss'],
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'app.bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        query: {
          presets: ['env'],
        },
      },
      {
        test: /\.(sass|scss)$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          'css-loader',
          'postcss-loader',
          'sass-loader',
        ],
      },
      {
        test: /\.html$/,
        use: [
          'raw-loader',
          {
            loader: 'twig-html-loader',
            options: {
              data: options,
            },
          },
        ],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      // Options similar to the same options in webpackOptions.output
      // both options are optional
      filename: '[name].css',
      chunkFilename: '[id].css',
    }),
    new CopyWebpackPlugin([
      {
        from: './src/static/',
        to: './static/',
      },
    ]),
    ...generateHTMLPlugins(),
  ],
  stats: {
    colors: true,
  },
  devtool: 'source-map',
};

And this does work, however, if i change anything under _partials directory, changes are not being visible in browser.

If i restart webpack-dev-server, changes are pulled in :(

Any ideas what should be changed to make it work?

Twig function "source" and relative paths

There is Twig function source which returns the content of a template without rendering it. One useful use of this function is to insert the svg file into the final HTML.
However, this only works if we specify the full path to the inserted file relative to Webpack context.

I.e. let's assume that we have such a file structure

src/
  |-- assets/
       |-- file.svg
  |-- index.twig
  |-- index.js

the content of index.twig looks like this:

<div>{{ source('....') }}</div>
  • if we use <div>{{ source('./assets/file.svg') }}</div> then the result HTML contains "Template "./assets/file.svg" is not defined." instead of content of SVG file
  • if we use <div>{{ source('assets/file.svg') }}</div> then the result HTML contains "Template "assets/file.svg" is not defined." instead of content of SVG file
  • if we use <div>{{ source('src/assets/file.svg') }}</div> then the result HTML contains content of SVG file

Files to reproduce this behavior are attached.

Any ideas how to fix this?

twig-resolve.zip

Loader adds extra separators into namespaces

// webpack.config.js
// ...
namespaces: {
   'layouts': `${src}/twig/layouts`,
   'components': `${src}/twig/components`,
},
// ...
{% import "@components/footer.twig" as footer %}
ERROR in ./source/twig/index.twig (./node_modules/html-webpack-plugin/lib/loader.js!./source/twig/index.twig)
 Module build failed (from ./node_modules/twig-html-loader/index.js):
NonErrorEmittedError: (Emitted value instead of an instance of Error) TwigException: Unable to find template file /app/source/twig/components//////////footer.twig
     at runLoaders (/app/node_modules/webpack/lib/NormalModule.js:298:13)
     at /app/node_modules/loader-runner/lib/LoaderRunner.js:367:11
     at /app/node_modules/loader-runner/lib/LoaderRunner.js:233:18
     at Object.context.callback (/app/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
     at Object.loader (/app/node_modules/twig-html-loader/index.js:87:10)

[QUESTIONS] Few questions about this loader with HtmlWebpackPlugin

Hi there,

I'm new in this webpack world and I'm practicing using the webpack step-by-step guide.

I'm using twig as a template engine and I wonder if I can inject my js bundles into a twig template.

What is what I want

Well my goal is to render the twig template with javascripts injected in specific place and if it is possible, replace some values given at loader / plugin options.

First I'll expose my webpack.config.js, then my twig templates and finally the rendered result which is not the desired..
Then I'll expose the desired result.

My files right now:

{# src/web/views/base.twig #}
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{% block title %}{% endblock %}</title>
        <meta name="description" content="{{ meta_content }}">
        <meta author="{{ author }}" content="{{ author_content }}">

        {% block stylesheets %}{% endblock %}
        {% block head_scripts %}{% endblock %}
        {# WANT TO BE INJECTED HERE print.bundle.js SCRIPT #}
    </head>

    <body>
        {% block body %}{% endblock %}
        {# WANT TO BE INJECTED HERE app.bundle.js SCRIPT #}
        {% block scripts %}{% endblock %}
    </body>
</html>
{# src/web/views/index.twig #}
{% extends "base.twig" %}

{% block title %}{{title}}{% endblock %}
{% block body %}
    <h1> Hi world </h1>
{% endblock %}
// webpack.config.js 
const path = require('path');

// https://github.com/jantimon/html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

    entry: {
        app: './src/web/client/index.js',
        print: './src/web/client/print.js'
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './src/web/views/index.twig',
            filename: '../../views/index.test.twig'
        })
    ],
    mode: 'production',
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'src/web/public/js')
    },

    // path resolution on imports
    // https://webpack.js.org/configuration/resolve
    resolve: {
        // https://webpack.js.org/configuration/resolve/#resolvealias
        alias: {
            // key-> alias, value: string -> path to be resolved
        }
    },
    // https://webpack.js.org/configuration/module/
    module: {

        // can apply rules to use loaders!
        // https://webpack.js.org/configuration/module/#modulerules
        rules: [
            {
                test: '/\.twig$/',
                use: [
                    'raw-loader',
                    {
                        loader: 'twig-html-loader',
                        options: {
                            data: {
                                title: 'HALLO'
                            }
                        }
                    }
                ],
                
            }
        ]
    }
}

Rendered result

(src/web/views/base.twig untouched)

{# index.test.twig #}
{% extends "base.twig" %} {% block title %}{{ title }}{% endblock %} {% block body %}<h1>Hi world</h1> {% endblock %}<script src="../public/js/app.bundle.js"></script><script src="../public/js/print.bundle.js"></script>

I event tried to render as index.html, but the result is still the same...

So this is what I want to be rendered:

{# src/web/views/base.twig #}
<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>{% block title %}{% endblock %}</title>
        <meta name="description" content="{{ meta_content }}">
        <meta author="{{ author }}" content="{{ author_content }}">

        {% block stylesheets %}{% endblock %}
        {% block head_scripts %}{% endblock %}
        <script src="./js/print.bundle.js"></script>
    </head>

    <body>
        {% block body %}{% endblock %}
        <script src="./js/app.bundle.js"></script>
        {% block scripts %}{% endblock %}
    </body>
</html>
{# index.test.twig #}
{% extends "base.twig" %} {% block title %}HALLO{% endblock %} {% block body %}<h1>Hi world</h1> {% endblock %}

I want to keep the twig template because I have a Node.js server that renders the template. However, I want webpack injects the bundles as it says in this guide: https://webpack.js.org/guides/output-management/#setting-up-htmlwebpackplugin

So I readed many times the docs about this loader and htmlwebpackplugin but without success...

I want to know what I'm doing wrong, and how CAN I ACCOMPLISH MY GOAL.

Thank you so much.

Why use raw-loader ?

I do not uderstand why we need to use raw-loader.
What part of the job twig-html-loader and raw-loader do?

data option could be a function

Data option is currently an object.
I would be able to get a json related to the current twig file as data
So I need a function with current file path as a parameter.
Could it be possible ?

Named parameters

I guess this might even be a but with twigjs in general. Currently templates that have something like {{ theme_asset('path/to/asset', version = asset_reset) }} does not work and exits with parsing error

Webpack rebuild with options data update

My current options look like this:

options: {
  data: {
    options: require( path.join(__dirname, '/src/html/_data/options.json') ),
    global: require( path.join(__dirname, '/src/html/_data/global.json') ),
  }
}

Is there a way to recompile webpack when one of the json files changes? I can watch for file changes with devserver, but that will not rebuild what's in memory already.

Possible memory leaks?

In my project with around 100 pages (plus tons of twig imports, macro , etc...) I see the regrasion of RAM memory from 2G to 8G in couple of builds and then webpaack throw "out of memory" error.
I quick looked in to source code of this loader and have some questions, why we every time init Twig then function called? Why not setup Twig once and then use it in next call?

//setup twig here
const Twig= ....

module.exports = function loader(source) {
...
}

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.