Skip to content
This repository was archived by the owner on Apr 11, 2018. It is now read-only.

Extract file system based functions into template loaders #377

Closed
wants to merge 3 commits into from

Conversation

MaratFM
Copy link
Contributor

@MaratFM MaratFM commented Dec 30, 2013

I hit the same issue as #370 when I tried to use swig in browser. Precompiling templates is not useful in some cases and does not work with latest code. That is why I tryed to fix it and and add some flexibility.

Loaders provides interface for extending swig for using different template sources. By default FileSystemLoader will be used and it acts as current swig implementation. As an example I added MemoryLoader which might be used in browser. It loads templates from predefined hash object.

I know that my pull request needs to be updated with more documentation and tests, but I want to know you opinion about it before.

Thank you

@maldn maldn mentioned this pull request Dec 30, 2013
@gleitz
Copy link

gleitz commented Dec 30, 2013

In the test you use

s = new Swig({ loader: new loaders.MemoryLoader(templates) });

What would this look like on the client (browser)?

Does this also address "include" in the browser or just "extends"?

@MaratFM
Copy link
Contributor Author

MaratFM commented Dec 31, 2013

MemoryLoader must work with both extends and imports in browser. It just emulates file system via predefined dictionary:

    templates = {
      'page.html': '<html>{% include "content.html" %}</html>',
      'content.html': 'Hello {{ name }}!'
    };

But It still needs to be improved for enabling relative paths (like "../base.html").

@maldn
Copy link

maldn commented Dec 31, 2013

I was about to implement something similar yesterday right before i saw your patch.
Needless to say that i like the idea :-)

One minor problem is that the loaders are not exported and not accessible when used with requirejs.
A simple "exports.Loaders = loaders;" in swig.js fixes that.
But its also very easy to define your own loader. In our case we need to load the templates via requirejs, so i just did that.

The bigger problem is, that when you try to use requirejs to load templates that extend other templates, swig calls getParents() which in turn calls parseFile().
getParents/parseFile only work synchronous without passing on a callback. This blows up.

I am not sure at this point if its feasible to clobber swig with callback-stuff to make it work with asynchrously loaded templates, or if it makes more sense to just set up a grunt task to collect and maybe even precompile all templates and use something like the MemoryLoader.
Ideally i don't have to force our developers to use grunt/a watcher.

Maybe @paularmstrong has some feedback if he would accept a patch that makes swig work with templates loaded with requirejs, even if it would mean passing on a callback to getParents/parseFile.

P.S.: Of course we could make every template, including its complete dependency-tree, a module dependency. But i'd rather not trace all dependencies by hand every time i want to extend a template.

@MaratFM
Copy link
Contributor Author

MaratFM commented Dec 31, 2013

A simple "exports.Loaders = loaders;" in swig.js fixes that.

done

In our case we need to load the templates via requirejs, so i just did that.

Good idea I thought to add it too.

getParents/parseFile only work synchronous without passing on a callback. This blows up.

I see, it is a real problem, because requires to make most of the methods async. I can try to do that in separate branch.

@maldn
Copy link

maldn commented Dec 31, 2013

i am really curious of what @paularmstrong has to say about this, as this (as far as i understand) is a fairly big change to swig.
but i think it is the way to go. perhaps using some sort of promise pattern.

@paularmstrong
Copy link
Owner

Really nice work, @MaratFM. I need some time to dig into this and potentially make some changes, unless you would prefer to make changes based on my requests.

But It still needs to be improved for enabling relative paths (like "../base.html").

We should add in the path.resolve code from the FileSystem loader into the Memory loader. That module is available in the browser, thanks to Browserify. So, using it should fix relative paths into "absolute" paths (e.g. ../base.html would turn into base.html). Also, the memory loader should try both with and without the leading slash and convert windows-based paths (C:\ [or whatever it is] and \) to unix-style (/).

I'm sure we can pick at this forever, but those are a couple things that we should definitely take care of before merging.

Sidenote: I'm not sure why tests are suddenly failing. As long as we make them pass when working locally, we should be fine.

@maldn
Copy link

maldn commented Dec 31, 2013

a couple of hours ago i did not see any failing tests. altough there were some conflicts i resolved in https://github.com/AffiliPRINT/swig/commit/5e8e745ab50334e05d1766ffa6f944f35a9aec46

@paularmstrong
Copy link
Owner

I've already merged this locally and am taking it over with some changes and adding documentation... more to come soon...

@paularmstrong paularmstrong mentioned this pull request Jan 7, 2014
2 tasks
@paularmstrong
Copy link
Owner

Closing in favor of gh-384 (since I can't push changes to a pull request). @MaratFM: If you want push access to be able to continue to contribute to the branch/feature, just let me know!

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.

4 participants