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

Missing content when an async extension is used inside a sync extension #1363

Open
CodeFoodPixels opened this issue Jul 7, 2021 · 4 comments

Comments

@CodeFoodPixels
Copy link

I've come across this issue while using @11ty. The content from an async extension isn't ready by the time a parent sync extension is ready to render, and thus will not display any child content from that async extension.

I've produced a failing test in #1362

@ogonkov
Copy link
Contributor

ogonkov commented Jul 9, 2021

Can you please test it with #1357?

@CodeFoodPixels
Copy link
Author

I gave it a quick test the other day and it didn't seem to work. I'm moving house this weekend so I cannot do any more investigation

@MadeByMike
Copy link

MadeByMike commented Oct 27, 2021

@CodeFoodPixels I think there are a few problems with this test. If you remove custom sync tag it fails anyway... I think because you need to call CallExtensionAsync with the Asyc example and we need to call render() rather than the expect() util to test async examples correctly.

Here's what I came up with locally and this worked:

it('should allow async custom tag within sync custom tag compilation', function(done) {

  function TestSyncExtension() {
    this.tags = ['testsync'];

    this.parse = function(parser, nodes) {
      var content;
      var tag;
      parser.advanceAfterBlockEnd();

      content = parser.parseUntilBlocks('endtestsync');
      tag = new nodes.CallExtension(this, 'run', null, [content]);
      parser.advanceAfterBlockEnd();

      return tag;
    };

    this.run = function(context, content) {
      // Reverse the string
      return content().split('').reverse().join('');
    };
  }

  function TestAsyncExtension() {
    this.tags = ['testasync'];

    this.parse = function(parser, nodes) {
      var content;
      var tag;
      parser.advanceAfterBlockEnd();

      content = parser.parseUntilBlocks('endtestasync');
      tag = new nodes.CallExtensionAsync(this, 'run', null, [content]);
      parser.advanceAfterBlockEnd();

      return tag;
    };

    this.run = function(context, body, callback) {
      // Uppercase the string
      setTimeout(() => {
        console.log({context, body, callback});
        
        callback(null, body().toUpperCase());
      }, 1);
    };
  }
  

  // First prove it works normally
  render(
    '{% testasync %}abcdefghi{% endtestasync %}',
    null,
    {
      extensions: { TestAsyncExtension: new TestAsyncExtension()},
      autoescape: true
    },
    function(err, res) {
      expect(res).to.be('ABCDEFGHI');
    }
  );
    
  // Then fails with custom tag (also fails with include, but I don't know how write a test for this, include is probably a sync tag anyway?)
  render(
    '{% testsync %}{% testasync %}abcdefghi{% endtestasync %}{% endtestsync %}',
    null,
    {
      extensions: { TestExtension: new TestAsyncExtension(), TestSyncExtension: new TestSyncExtension()  },
      autoescape: true
    },
    function(err, res) {
      expect(res).to.be('IHGFEDCBA');
    }
  );

  finish(done);
});

I didn't want to make a competing PR but if you don't have time on this one I'd like to try and follow it up.

@CodeFoodPixels
Copy link
Author

Thanks @MadeByMike, I've just updated my test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants