On 12 August 2011 12:34, Robert Forkel <[email protected]> wrote:
> I think I'm using the correct pyramid APIs to get the translator.
> Here's how I do it:
>
> def get_deform_translator(request):
> tsf_deform = translationstring.TranslationStringFactory('deform')
> return lambda s, m=None:
> pyramid.i18n.get_localizer(request).translate(tsf_deform(s, m))
This looks like you're trying to set up auto-translation for common
strings, i.e. to provide the translation machinery with a translation
domain ("deform").
That's something else entirely than getting the right locale
(language, essentially) set up per request.
> And I follow recipe
> http://docs.pylonsproject.org/projects/pyramid_cookbook/dev/i18n.html
> to attach a localizer to a request (which is retrieved in the above
> function).
That section is about Mako though and how to turn strings into
"translation strings" (which have a domain and may have a value
mapping dict).
> The problem still stands: One chameleon TemplateLoader instance (e.g.
> the one in deform.template.default_renderer) doesn't work, because it
> caches PageTemplateFile instances per filename and disregards
> potentially different translators - i.e. it will just keep the
> PageTemplateFile with the translator passed at the time it was put in
> the loader's registry. So when a form with invalid data is submitted
> using a different locale, the error messages will be in the wrong
> language.
That's because it's meant to be dynamic. There's only ever one
``PageTemplateFile`` per template, regardless of the locale or other
argument passed. It's all managed by the framework and you just have
to attach the right locale to the request.
Let me paste the conditions again:
- First, the negotiator looks for the ``_LOCALE_`` attribute of
the request object (possibly set by a view or a listener for an
:term:`event`).
- Then it looks for the ``request.params['_LOCALE_']`` value.
- Then it looks for the ``request.cookies['_LOCALE_']`` value.
- Finally, the negotiator returns ``None`` if the locale could not
be determined via any of the previous checks (when a locale
negotiator returns ``None``, it signifies that the
:term:`default locale name` should be used.)
You can subscribe to the ``INewRequest`` event to set this up per request.
\malthe
> What I do now looks like this (in the main function of my pyramid app):
>
> settings['deform_renderers'] = {}
> for locale in settings['msp.main.langs.list']:
> settings['deform_renderers'][locale] =
> deform.template.ZPTRendererFactory(
> (pkg_resources.resource_filename('gulpdeform',
> 'templates'), deform.template.default_dir),
> auto_reload=False,
> debug=False,
> )
>
> config = Configurator(
> settings=settings
> )
>
> Ideally I would want to pass a translator for each locale right away,
> but I wanted to use pyramid's make_localizer function, which isn't
> useful until later in main, when I'm done registering translation
> directories. So instead I assign the translator the first time I'm
> using the renderer, before instantiating a deform.Form:
>
> if not renderer.translate:
> t = get_deform_translator(request)
> renderer.translate = t
> renderer.loader.kwargs['translate'] = ChameleonTranslate(t)
>
> This works well enough to not feel like a problem anymore; it just
> looks hacky. So for my use case, a TemplateLoader which accepts a
> translator as parameter to the load method would be the better API -
> but may be impossible, because a translator cannot be used as
> dictionary key ... Having to pass the translator as constructor
> argument to TemplateLoader means I must have one TemplateLoader
> instance per translator.
>
> best,
> robert
>
> On Fri, Aug 12, 2011 at 10:54 AM, Malthe Borch <[email protected]> wrote:
>> On 12 August 2011 10:05, Robert Forkel <[email protected]> wrote:
>>> hm. I do not really follow. I'll try to explain my problem in more
>>> detail. First, I only use Chameleon from within deform, the rest of my
>>> app uses mako. Now I noticed that form rendering was slow and that was
>>> because of the template loader parsing the templates all the time.
>>> As far as I can see in chameleon.loader, the caching is done per
>>> instance of TemplateLoader. Now deform instantiates a TemplateLoader
>>> when a deform.template.ZPTRendererFactory is instantiated. When using
>>> the default_renderer this is only done once on import of deform and
>>> caching will work - i guess. But to be able to pass a translator per
>>> request, I instantiate a new ZPTRendererFactory per request as well -
>>> and no caching is possible.
>>
>> I see.
>>
>> What I can tell you is that Pyramid wants to do this for you, i.e. it
>> automatically sets a translator for you. Instead of trying to do this
>> yourself, it would be better to use the built-in language negotiation.
>>
>> If you're still unsure, maybe let's try and see your code to see if
>> something's funky in your setup.
>>
>> \malthe
>>
>> --
>> You received this message because you are subscribed to the Google Groups
>> "pylons-discuss" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> For more options, visit this group at
>> http://groups.google.com/group/pylons-discuss?hl=en.
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "pylons-discuss" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/pylons-discuss?hl=en.
>
>
--
You received this message because you are subscribed to the Google Groups
"pylons-discuss" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/pylons-discuss?hl=en.