Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow user defined tags for js injection #1234

Closed
wants to merge 6 commits into from

Conversation

gnulnx
Copy link

@gnulnx gnulnx commented Jul 2, 2019

Provide support for injection of JS assets into custom tags. Currently the html-webpack-plugin will insert into the end of the head or body section depending upon the inject setting. This PR provides support to allow a user to define a different element to insert the script tags into.

Reasoning behind this is often times template engines will build upon base templates. For instance in a django application a user often defines a base.html template that would define the entire head and body sections and then provide something like a content {% block content %}{% endblock %}. The idea being that the user would then extend this base template into say home.html, about_us.html, etc.

The problem is that webpack sees the html before the other the django templating system (which is runtime). It is currently possible to have webpack insert all js into the base.html template. However, this is not desierable. In a multiplage web application each page is likely to contain it's own JS code.

With this pr the user can now do something like this in weback.conf

...
inject: webpack-inject-js
...
...

Then in any templates they want to inject js into they would simply add their custom tag to the end.

<webpack-injected-js></webpack-injected-js>

@gnulnx
Copy link
Author

gnulnx commented Jul 2, 2019

Failing test is also failing for me locally in master branch...

● HtmlWebpackPlugin Examples › pug-loader example

expect(received).toEqual(expected) // deep equality

- Expected
+ Received

@@ -253,12 +253,11 @@
      return '';
    }
    if (val === true) {
      return ' ' + (terse ? key : key + '="' + key + '"');
    }
-   var type = typeof val;
-   if ((type === 'object' || type === 'function') && typeof val.toJSON === 'function') {
+   if (typeof val.toJSON === 'function') {
      val = val.toJSON();
    }
    if (typeof val !== 'string') {
      val = JSON.stringify(val);
      if (!escaped && val.indexOf('"') !== -1) {

  51 |         const file1Contents = fs.readFileSync(path.join(diff.path1, diff.name1)).toString();
  52 |         const file2Contents = fs.readFileSync(path.join(diff.path2, diff.name2)).toString();
> 53 |         expect(file1Contents).toEqual(file2Contents);
     |                               ^
  54 |       });
  55 |
  56 |       expect(res.same).toBe(true);

@jantimon
Copy link
Owner

jantimon commented Jul 7, 2019

Hey @gnulnx you can just turn of inject and use a lodash template to inject the styles / js code.

With html-webpack-plugin 4.x that was simplified a lot.

To add all head tags (meta tags and styles) you can write:

<%= htmlWebpackPlugin.tags.headTags %>

To add all body tags (scripts) you can write:

<%= htmlWebpackPlugin.tags.bodyTags %>

Please let me know if that helps you

@gnulnx
Copy link
Author

gnulnx commented Jul 8, 2019

Hey @gnulnx you can just turn of inject and use a lodash template to inject the styles / js code.

With html-webpack-plugin 4.x that was simplified a lot.

To add all head tags (meta tags and styles) you can write:

<%= htmlWebpackPlugin.tags.headTags %>

To add all body tags (scripts) you can write:

<%= htmlWebpackPlugin.tags.bodyTags %>

Please let me know if that helps you

@jantimon Yes the lodash template tags work and this is what I've been doing for a year or so. I just found it kinda cumbersome to have to add that much boiler plate to each template and figured if we could insert into the head or body it should be straight forward to insert at any tag and not have to add the full lodash boiler plate to each injection point.

@ejez
Copy link

ejez commented Oct 27, 2019

@gnulnx you can keep the <head> and <body> tags in the html-webpack-plugin template, and at the same time extend it from a django base.html template that already has these tags with the help of {{ block.super }}

(No need to disable inject)

base.html

{% block html %}
<!DOCTYPE html>
<html {% block html_tag_attributes %}{% endblock %}>
  <head>
    {% block head %}
      <meta charset="utf-8">
    {% endblock %}
  </head>

  <body {% block body_tag_attributes %}{% endblock %}>
    {% block body %}
      {% block content %}{% endblock %}
    {% endblock %}
  </body>
</html>
{% endblock %}

index.html (template used by html-webpack-plugin to generate bundles/webpack/home_page.html):

{% extends "base.html" %}
{% load static %}
{% block html %}
<!DOCTYPE html>
<html {% block html_tag_attributes %}{{ block.super }}{% endblock %}>
  <head>
    {% block head %}{{ block.super }}{% endblock %}
  </head>
  <body {% block body_tag_attributes %}{{ block.super }}{% endblock %}>
    {% block body %}{{ block.super }}{% endblock %}
  </body>
</html>
{% endblock %}

home_page.html

{% extends "bundles/webpack/home_page.html" %}
{% block content %}
  Adding content here...
{% endblock %}

You don't need to create multiple templates for html-webpack-plugin, create only one by extending from the point your django pages start diverging, then continue extending from the webpack generated templates to your final django page templates.

Example:

Let's say you have two pages: "Home" and "About" that share the same "layout"

base.html ==> layout.html ==> index.html (html-webpack-plugin template)

You will get two generated templates that you can extend:

webpack/home.html ==> home.html (final django template to display "Home")
and
webpack/about.html ==> about.html (final django template to display "About")

Note: the links in the injected tags can be easily converted to django static tempate tag format, ie: 'bundles/js/main.js' ==> {% static 'bundles/js/main.js' %}
I created a minimal basic plugin to do this: https://gitlab.com/noor-projects/django-static-webpack-plugin

@jantimon jantimon closed this Mar 24, 2020
@lock lock bot locked as resolved and limited conversation to collaborators Apr 25, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants