Hi there
>> I agree with Robert's take on this. It doesn't work to have multiple
>> trees, one per language.
>
> Doesn't work in what context, though? There clearly are a lot of
> successful websites out there that have top level language folders. I
> can certainly see use cases where this is very valid.
It doesn't work in Plone, in terms of Folders with Pages and so on. I'm
not talking about URL structures, that's another topic ..
> I'm not trying to shoot you down, I just want to make sure we're not
> getting too one sided.
Yup, appreciated.
>> When a folder is translated, the translation should be stored as an
>> annotation or subobject of the folder.
>
> This is certainly possible. But then how do you ensure that the user
> sees the correct thing when they navigate to the folder? A redirect?
> Some kind of view level magic to pull data from the annotation?
What I18NLayer did was (much shortened):
def getObject(self):
layer=self.Layer()
language_tool = getToolByName(layer, 'portal_languages', None)
for lang in self.Languages():
if hasattr(base, lang):
ob = getattr(layer, lang)
return ob
I.e. it returns the appropriate child object instead of the container
for the translations.
But I'm sure there's many other ways of implementing this.
>> In the case of a page, translations are siblings, and referenced by
>> the 'translationOf' relationship. In the case of a folder, the
>> reference could be to a child object, which is the translation. The
>> exceptional handling required in the case of a folder, would be to
>> make the appropriate child object appear in the place of the folder
>> when rendering and editing.
>
> Right. This isn't so easy to do properly and transparently. :)
Yes. I'd prefer a way that requires as little exceptional handling as
possible, as mentioned in my previous message.
If it were easy, it probably would have been done ages ago ..
> You're right of course, but I'm not sure that a top level language
> folder necessarily forces you to choose between linguistic
> classification and containment structure. One advantage is that you
> can have URLs that reflect the target language, so e.g. you have
> /en/news/new-logo and /no/nyheter/ny-logo. The URL also gives a clear
> indication of the language, which can be helpful in some cases.
I'm not mad about having the language code in my face for all eternity.
I'd prefer it if
http://site/news/new-logo remained possible. In the
case of I18NLayer, 'new-logo' would refer to the translation container,
which contains
http://site/news/new-logo/en and
http://site/news/new-logo/no -- browsing to
http://site/news/new-logowould return the 'en' child if that is your preferred language. If you
wanted to refer someone to a specific language, you can send them
http://site/news/new-logo/en or
http://site/news/new-logo/no.
For me, translated URLs are not a must-have. For example, as far as I
can tell
http://www.bangkokshuho.com/servicedapartment/index.htmldoes not even have an English version. (As an aside, I feel that URLs
with ideograms or other non-ASCII characters in them are too painful to
mention further.)
However, translated URLs are perfectly doable (and valuable) using an
approach like the SEOptimizer I mentioned.
> I think some kind of proxying approach is worth considering, although
> I know a lot of people (myself included) have tried and failed to do
> this before.
Yes, it may turn out to be a dead end .. but I wouldn't want to write it
off out of hand.
> The idea is that your view may have:
>
> tal:replace="context/title"
>
> but under the hood, there's a __getattribute__ on context that tricks
> it into returning the value of the 'title' attribute in the target
> language, with possible fallback if there is no translation.
In the case of I18NLayer (which I'm only harping on because I've used
it, and it's one of the fallen-by-the-wayside ideas that may deserve a
second look), 'context' may refer to two things. In the case of
http://site/news/new-logo it would refer to the translation container
proxy, which always looks up the appropriate translation and finds
'title' or whatever on it. Again, brutally shortened:
method=I18NLayer.inheritedAttribute(name)
if callable(method): return apply(method, args, kw)
else: return method
In the case of
http://site/news/new-logo/en it just refers to a normal
Plone object, and there's no need for trickery.
> This still creates a raft of problems. What do you do with things that
> are not simple attributes? How do you handle security? How do you
> handle workflow? What about auxiliary content like portlets?
I don't think these issues are specific to this case ..
However, I18NLayer is OK with anything that answers to getattr, e.g.
simple attributes, fields, methods. Nothing special is done for
security, 'en', 'no' and so on are Plone objects with the usual checks.
Similarly, they are workflowed individually. Retracting all translations
at once, or blocking publication until all translations have been
reviewed are legitimate use cases, but I don't think that hard with this
model.
> It also assumes that every content class has this hook and that it's
> never overridden, which probably isn't a safe assumption.
Fully agreed, I wouldn't want to make an assumption like that.
> Therefore, you probably need to use some kind of translation proxy.
> This may be quite possible, of course. It's not much different to Zope
> 3 security proxies, for example.
Yes, when I'm talking about I18NLayer, some kind of translation proxy is
exactly what I'm talking about.
> But even if we do support this, it's *still* a special case. Language
> fallback and single-tree structuring is not going to be appropriate
> for everyone, and will almost invariable involve some kind of
> trade-off that others may not want.
Quite true. I doubt any implementation will be able to cater to every
case.
This approach doesn't mandate language fallback, though. It just makes
it possible. It's true that it does not accommodate separate
per-language folder hierarchies.
I should try to say why I don't like separate per-language folder
hierarchies (in terms of Plone content. In terms of URL structure is
another story, which I also don't like but for a different reason,
mentioned above). Say we have
http://site/en/school123/sports/football/first-team and it is not yet
translated. I click on 'translate' on 'first-team', and I have to
provide translations for the parent folders first (or I have to go and
translate each of them individually first). This results in three new
folders. 'first-team' has to refer to 'erste-spann' (please forgive my
German) by UID. If I delete 'first-team', does 'erste-spann' remain?
(I.e. do I mean to delete the translation or the document?) If I'm
deleting the document, does 'schule123/sportarten/fussball/' also get
tidied away if there's no other German content? What do I do if I want
to workflow individual translations, or all of them together? If I move
'sports' to 'activities/sports', does that trigger a cascade of moves
(to 'activitaeten/sportarten', etc.)? Does the move block unless
'activities' has already been translated in all languages?
I mention these issues as none of them come up with the I18NLayer
approach (counter-issues welcome). I can translate the folders when I
get around to it, if I want to workflow or delete a translation I do so
at e.g. 'first-team/en', if I want to do them all together I do so at
'first-team'. I don't need a reference catalog to see which documents
are translations of which others. If a document doesn't have
translations, it doesn't need a proxy (i.e. 'first-team' is an English
Page until it gets translated, at which point it moves to a Page called
'en' contained within a translation container called 'first-team').
I don't like stubs with copies of the canonical language either. Having
the same content in the database 5 times for 5 languages is a drag if it
isn't really unavoidable. It's bearable for mostly-translated sites, but
for more sparsely translated sites it's not pretty.
It's true that having 'first-team' as id which shows in the final URL is
not ideal (though as I said I don't think it's all bad). Having this id
be the id of the object in the database is arguably even worse, but we
love this, don't we? ;-) It has bad side effects in other contexts as
well. For example .. a simple rename of a parent folder containing many
subfolders full of documents, triggering a recatalog from hell, oh my!
Regards,
--
jean . .. .... //\\\oo///\\
------------------------------------------------------------------------------
_______________________________________________
Plone-developers mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/plone-developers