Skip to content

Overriding block in include results in duplicate content #2703

@NoNameProvided

Description

@NoNameProvided

I don't know if this is the expected behavior or not, but I would like to start a discussion about the scope of the extend & include commands are shared.

Now the current behavior is that a pug file which extends another share it's scope in a strange way with it's included templates. I find this behavior odd, as it restricts your structure to be one level deep maximum.

Here is an example, having the following three files in a directory:

//- base.pug
doctype html
html
  head
    block options
    - var title = (options && options.title) ? options.title : "Default title"
    //- ...
    link(rel='stylesheet' href='/bundle.css')
    //- ...
    base(href='/')

    title #{title}

  body
    block content
    script(src='/shared-bundle.js')
    block scripts
//- component.pug
block scripts
  script(src='/js/footer.component.js')

div.c-component
  p Content of the component.
//- page.pug
extends ./base.pug

block options
  - var options = { title: 'Pug Test' }

block scripts
  script(src='/js/test.page.js')

block content
  .p-test
    p Content of the page.
    include ./component.pug

This will generate the following html when running the pug --pretty --out dist/ page.pug command with the pug-cli.

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="/bundle.css">
    <base href="/">
    <title>Pug Test</title>
  </head>
  <body>
    <div class="p-test">
      <p>Content of the page.</p>
      <script src="/js/footer.component.js"></script>
      <div class="c-component">
        <p>Content of the component.</p>
      </div>
    </div>
    <script src="/shared-bundle.js"></script>
    <script src="/js/footer.component.js"></script>
  </body>
</html>

As you can see the footer.component.js file which was defined in the component.pug is included twice. Once (in my opinion) in it's right place at the end of the html file inside the base.pug scripts section, but its included in another place before the component.

So the following snippet in the component.pug template cause two strange side effect:

block scripts
  script(src='/js/footer.component.js')

First the footer.component.js file is included twice, second, the /js/test.page.js file defined in the page template is not included.

If I remove the scripts block from component.pug and simply add the script tag, then the /js/test.page.js file gets included properly at its place.

The expected behavior would be to be able to use blocks in every child in the hierarchy, not just the first one.

This behavior is clearly odd, and I think it's a bug. If not then the reason for this should be explained in the docs.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions