smhg / gettext-swig

Extract translatable strings from Swig template strings.
MIT License
1 stars 2 forks source link

[NFR] Support both {{}} and {%%} formats to support entire Django template family #1

Closed dschissler closed 9 years ago

dschissler commented 9 years ago

It appears that {{ }} always uses paranthesis and that {% %} doesn't. They are intended for different uses but that so far appears to be the only constant as different engines use them for different functionality. By supporting both of these formats the Swig parser can be used across the entire line of Django family templates (and there are several varieties).

smhg commented 9 years ago

This project will only support the Swig language. Other languages, as similar as they might be, can go in separate projects. Unless they are 100% interchangeable. But in that case, it is enough to create a parser for the original language.

dschissler commented 9 years ago

I think that this issue should be reopened. I made an issue on the Swig project and I received an insightful yet simple answer: Can a filter by implicitly used and default to empty string input?.

So it is perfectly valid to use the {{ t('message }} format in Swig. In my use I would just extend the data object passed into a Swig template to include a variable named t and n. So this is very valid and just represents another use of Swig. One approach extends the language and the other uses a function.

dschissler commented 9 years ago

@smhg You are probably enjoying your family now but I'm not sure if you would see my previous comment since the issue is closed and so I'm giving this notification.

smhg commented 9 years ago

Thank you for investigating this. I indeed didn't know you can call these filters in a regular function-style. So that would mean you would write things like:

{{ t('Translate this') }}
{{ t('Singular', 'Plural', count) }}

Am I right? Both single and double quotes are allowed I assume?

If I understood it right, this is definitely a valid todo.

dschissler commented 9 years ago

I indeed didn't know you can call these filters in a regular function-style.

According to Swig lore, filters are functions that can only be accessed by piping. To get {{ t('abc') }} you would simply pass in a function and name it t. So to use it in the helpers one would extend in the user data array object with the helper functions and built in system constants like DEV, etc.

You know what? I really suck at parsing complex stuff as I went the math/science route and then forgot it all.

I adapted this from your code:

exp = new RegExp([
  '{{\\s*',
  '(' + Object.keys(keywordSpec).map(escapeRegExp).join('|') + ')',
  '\\(',
  '(.*)',
  '\\)\\s*}}',
  ].join(''), 'g');

That gets the juicy argument expression and then from there I don't know how to easily parse that and simple methods like splitting or passing into eval either fail really easily or are very insecure. I've put a feeler out for a bit of javascript code to parse that part.

dschissler commented 9 years ago

Am I right? Both single and double quotes are allowed I assume?

Yes.

dschissler commented 9 years ago

JSON.parse('[' + match[2] + ']') is the obviously easy way to get an array and it takes care of security issues. I'll blame the wine for not seeing that trivially easy answer.

[edit] Unfortunately this doesn't handle single quoted arguments.

smhg commented 9 years ago

Can you create a jsfiddle where you apply your helper format in an example Swig template and get the result rendered accordingly? I'll then have something to work with when I adapt the parser. Thanks!

dschissler commented 9 years ago

This solution does the trick.

smhg commented 9 years ago

Thanks! I'll see what I can do.

dschissler commented 9 years ago

Any progress on this?

So I was thinking about this and what is language definition of a function call with parenthesis and quotes? Is it a context-free grammar? There must be a library snippet out there to parse that function call.

smhg commented 9 years ago

Thank you for the reminder. I've updated the source to support only filters ({{ _('something') }}).

After re-reading this thread and the Swig docs, that is probably the most common use-case. Tags are meant for block scope as I get it. It would be nice to have proper support for them too, but the previous implementation wasn't doing that.

dschissler commented 9 years ago

@smhg Just a minor nitpick but I was directly told by a Swig developer some weeks ago that this form is not a "filter" but a "function". In Swigland a filter must be piped a value to transform. That was the discussion that lead us to where we are at now.

smhg commented 9 years ago

Thanks for the explanation. Did the new version work for you?

dschissler commented 9 years ago

I haven't tried the latest one yet. I'm working on creating a webpack loader for nunjucks. I like it better than Swig. Same syntax though.