Hi, >I wouldn't say that this totally disqualifies it. If there is really a >big use case for people translating without installing django (which I >find kind of unlikely), a translation bundle can be created with the >extracted po files.
That's what I already do - provide ready extracted .po files. The problem is, if you want to update translations, you usually only need to parse sources. If I would have to introspect models to look for additional strings to be translated, I can only introspect those models that are active in my translation "project". But I might just not be able to do that, because I am just a translator - translators are not necessarily developers (actually in larger projects usually translators are _no_ developers, as the developers are far to lazy bastards to do translations ;-) ). So that's a real problem. If I need a _running_ instance of the model stuff to produce translations, I can't just use a checkout and use it. And pulling out the strings would still be rather complicated, even if I did introspection: .po files have line numbers for a reason. The reason is to allow translators to look at the source where the to-be-translated string is, to grokk the context. But please tell me how I am supposed to discover line numbers for attribute assignements? Sure, it _might_ be solveable, but in the end I think what would be needed to do it would be a limited python parser that knows about part of python (at least the definition part) and a way to designate model classes as model classes, so that we can pull strings from the definitions by just looking at the source (similar to what I do with the templates currently). But Python source analysis is much more complicated than just Django Template analysis. There might be some stuff in the AST tools for Python, but I never looked deeper into that, so I can't say how much work that might come out to be. >This could even be automated as an svn checkin >trigger, so it automatically updates the downloadable translation bundle >with every checkin to svn or on a periodic basis. I don't think that's really usefull, because you would get a much more complicated organization of translation files (and more complicated merging to do). The current approach uses just a command that you can run from the source tree to rebuild the .po files - this could be used by devs when they did add translations manually. If they forget to do it, users can easily run it themselves. That's why I want the make-messages.py to only rely on sourcecode parsing and not using any introspection and loading - that way users can translate everything, even if they can't or don't want to run it at the moment. >So the way to do this a bit less inefficiently is to have a keyword >argument to parse_until that prevents it from creating the blocktags in >the first place. Instead it just TemplateSyntaxErrors on anything but >plural or endtranslate, and rather than creating variable nodes it >creates the whole thing as a % formattable python string. Yes, but then the {% translate %} tag would be completely different in behaviour than other tags. It would be doable, and I do know how to turn it into something xgettext grokkable: xgettext _requires_ ngettext(...) for plural forms, it won't work with multiline stuff - but I can just turn the whole block into a one-line ngettext() call in my template-transformator and add empty lines accordingly, so that line numbers are again ok. And if I can be sure that there can't be any block tags inside the translate tag block, I can keep my template transformator quite simple (otherwise I would have to use the full Django template engine to keep track of those blocks). The syntax would have to be something like this (I give the results that the template translator that feeds xgettext would spew out, so that people knowing gettext can see what the results would be): {% translate "some string" %} this would be translated to _('some string') by the transformator. It could support variables as parameter, too (for gettext_noop marked strings that are translated on the fly from variable content). This would get another form: {% translate "some string" noop %} This would be gettext_noop('some string') - this is needed for database stored content that will be used untranslated here (to be stored in the database) but be translated by a {% translate row.col %} later on - think about values for hidden fields, for example. You want to allways store the english version, so that you can translate the content later on showing the field in lists for example. {% blocktranslate with variable|filter as name1 othervar|filter as name2 %} Text {{ name1 }} and {{ name2 }} {% endtblocktranslate %} This would become _('\nText %(name1)s and %(name2)s\n') {% blocktranslate count liste|counted as counter with variable|filter as name1 %} This is the singular {{ name1 }} {% plural %} This is the plural {{ name1 }} {% endblocktranslate %} This would become ngettext('\nThis is the singular %(name1)s\n', '\nThis is the plural %(name1)s\n', counter) That way xgettext would see standard stuff. But the problem here: the translation strings are not identical to what is stored in the .po any more. I don't know wether tools will stumble over this when using the linenumbers to go back to the sourcecode. I usually edit .po files just by using vi, but German is a rather simple language with regard to .po work ... Another thing I don't like: it's rather bloated in the templates. But then, the current stuff isn't really nice, either - but at least it's standard ;-) >All the things that need a filter applied to them are provided initially. Yep, grokked that. I still would prefer the more gettext-like syntax, especially since it would be the same both in the code and the templates, but I do understand the worries that template authors might be offput by the syntax - template authors aren't necessary programmers, much like translators aren't necessary programmers. bye, Georg