loops/loops/i18n
2024-10-02 12:54:34 +02:00
..
flags start working on Python3-compatible version 2024-09-23 17:30:48 +02:00
__init__.py start working on Python3-compatible version 2024-09-23 17:30:48 +02:00
browser.py more Python3 fixes: basic imports OK, starting with doctests 2024-09-24 15:30:46 +02:00
common.py work in progress: Python3 fixes 2024-09-24 11:13:49 +02:00
configure.zcml start working on Python3-compatible version 2024-09-23 17:30:48 +02:00
i18n_macros.pt start working on Python3-compatible version 2024-09-23 17:30:48 +02:00
README.txt more Python3 fixes 2024-09-27 08:40:20 +02:00
tests.py avoid testing deprecation errors with Python3.12 2024-10-02 12:54:34 +02:00

===============================================================
loops - Linked Objects for Organization and Processing Services
===============================================================

Let's do some basic set up

  >>> from zope.app.testing.setup import placefulSetUp, placefulTearDown
  >>> site = placefulSetUp(True)

  >>> from zope import component, interface

and setup a simple loops site with a concept manager and some concepts
(with all the type machinery, what in real life is done via standard
ZCML setup):

  >>> from loops.interfaces import ILoops, IConcept
  >>> from loops.concept import Concept
  >>> from loops.setup import ISetupManager

  >>> from loops.tests.setup import TestSite
  >>> t = TestSite(site)
  >>> concepts, resources, views = t.setup()
  >>> loopsRoot = site['loops']

  >>> from loops.knowledge.tests import importData
  >>> importData(loopsRoot)

  >>> from loops.knowledge.knowledge import Topic
  >>> component.provideAdapter(Topic)

For testing and demonstration purposes let's create a topic.

  >>> topic = concepts['topic']
  >>> topic01 = concepts['topic01'] = Concept('loops for Zope 3')
  >>> topic01.conceptType = topic


Content Internationalization
============================

Let's look at a certain concept that should contain i18n-alized data.

  >>> topic01.title
  'loops for Zope 3'

We can query the available languages, the current language setting and
the default language using a LanguageInfo object that is similar to a view.

  >>> from zope.publisher.browser import TestRequest
  >>> from loops.i18n.browser import LanguageInfo
  >>> langInfo = LanguageInfo(topic01, TestRequest())
  >>> langInfo.availableLanguages
  <AutoElement 'languages'>
  >>> langInfo.language is None
  True
  >>> langInfo.defaultLanguage is None
  True

In order to use content i18n we have to define the available languages
as an option on the loops root object.

  >>> loopsRoot.options = ['languages:en,de,it']
  >>> langInfo = LanguageInfo(topic01, TestRequest())
  >>> langInfo.availableLanguages
  ['en', 'de', 'it']
  >>> langInfo.defaultLanguage
  'en'
  >>> langInfo.language
  'en'

By setting an appropriate value in the URI we can select a certaing
language for processing of the current request.

  >>> input = {'loops.language': 'it'}
  >>> langInfo = LanguageInfo(topic01, TestRequest(form=input))
  >>> langInfo.availableLanguages
  ['en', 'de', 'it']
  >>> langInfo.defaultLanguage
  'en'
  >>> langInfo.language
  'it'

Let's now use a form to edit an i18n-sensible attribute. For this we have
to set up some components needed by the zope.formlib machinery.

  >>> from zope.publisher.interfaces.browser import IBrowserRequest
  >>> from zope.app.form.browser import TextWidget, ChoiceInputWidget, DropdownWidget
  >>> from zope.schema.interfaces import ITextLine, IText, IChoice
  >>> from zope.app.form.interfaces import IInputWidget
  >>> component.provideAdapter(TextWidget, (IText, IBrowserRequest),
  ...                          IInputWidget)
  >>> from loops.concept import ConceptTypeSourceList
  >>> from zope.schema.vocabulary import getVocabularyRegistry
  >>> getVocabularyRegistry().register('loops.conceptTypeSource', ConceptTypeSourceList)
  >>> component.provideAdapter(ChoiceInputWidget,
  ...          (IChoice, IBrowserRequest), IInputWidget)
  >>> component.provideAdapter(DropdownWidget,
  ...          (IChoice, ConceptTypeSourceList, IBrowserRequest), IInputWidget)

We also have to mark the attributes that should be stored in multiple
languages on the type object.

  >>> from loops.common import adapted
  >>> tTopic = adapted(topic)
  >>> tTopic.options = ['i18nattributes:title,description']

Now we are ready to enter a language-specific title.

  >>> from loops.browser.concept import ConceptEditForm, ConceptView
  >>> input = {'form.title': 'loops per Zope 3', 'loops.language': 'it',
  ...          'form.actions.apply': 'Change'}
  >>> form = ConceptEditForm(topic01, TestRequest(form=input))
  >>> form.update()

  >>> topic01.title
  I18NValue({'it': 'loops per Zope 3', 'en': 'loops for Zope 3'})

If we access an i18n attribute via a view that is i18n-aware we get the
value corresponding to the language preferences that appear in the request.

  >>> input = {'loops.language': 'it'}
  >>> view = ConceptView(topic01, TestRequest(form=input))
  >>> view.title
  'loops per Zope 3'

If there is no entry for the language given we get back the entry for
the default language.

  >>> input = {'loops.language': 'de'}
  >>> view = ConceptView(topic01, TestRequest(form=input))
  >>> view.title
  'loops for Zope 3'

There are also fallbacks - mainly for being able to access the title
attribute in not i18n-aware contexts - that retrieve the value corresponding
to the default language at the time of the attribute creation.

  >>> topic01.title.getDefault()
  'loops for Zope 3'
  >>> str(topic01.title)
  'loops for Zope 3'
  >>> topic01.title.lower()
  'loops for zope 3'

Viewing translations
--------------------

  >>> view.adapted.translations()
  {'it': 'loops per Zope 3', 'en': 'loops for Zope 3'}


Fin de partie
=============

  >>> placefulTearDown()