Jump to content

Module: Languages (multi language content management)


Oliver
 Share

Recommended Posts

PW's page cloning supports images/files too. I suppose it just depends when the cloning takes place as to whether the images are duplicated there. You never really know if an image is going to need to be language specific or not, though it's description (alt tag) would be. I tend to think it's best to follow a path of more duplication here rather than trying to squeeze out some efficiency benefits in less duplication. Either way, any kind of image or file mirroring would seem more like a luxury than a requirement, in my opinion. If I were building a multi-language site, I would probably keep some pages for shared assets (outside of the language trees) and pull shared images from there when necessary. I'd reserve the on-page image and file fields for language specific stuff, not to be cloned across trees.

But when sharing the files through a resource page, it would then only be possible to inserting them in tinymce, not for image fields on page?

So what if I like to have an image field allowing 1 image, to be able to be on a predefined place on the layout, and which is not language specific?

Link to comment
Share on other sites

Actually, I wasn't even thinking of TinyMCE, but you are right that would be an option. What I was thinking of was a shared assets page, and I use them on a lot of sites already. Language-specific pages could pull from those shared assets like any other page, i.e.

<?php

$masthead = $pages->get("/tools/shared/masthead/")->images->getRandom(1); 

$alt = array(
    'en' => 'Masthead',
    'de' => 'Impressum'
    ); 

$lang = $page->rootParent->name; 

echo "<img src='{$masthead->url}' alt='$alt[$lang]' />";
Link to comment
Share on other sites

  • 2 weeks later...

Thanks for the offer, Soma. Would help, if you tell about the functionalities you’d expect such a module to have. Maybe it gives me an hint for the one or other question I still have to get an answer for. ;)

The real complex thing still is to keep the page mapping (associating the different language's translations of a page with each other) consistent, while allowing pages to be moved, trashed or deleted and also to providing the possibility to have pages in a language tree that aren’t sync’ed with other languages.

I implemented a sync option to automatically sync a language with the defined default language. So creation and deletion of pages in default language’s page tree will be repoduced within the synced language’s page tree all the way.

Alternatively, you can deal with the translations manually by creating them from the language tab in the page edit form (as already said: by cloning as well as by creating an empty new page).

What would you guys suggest should happen, when a page is moved outside the language’s page tree or is trashed? On sync, I guess, the associated pages have to be deleted or–in case of being trashed–also be trashed.

I think it should also be trashed. That's just the most common.

But thinking about it, what would be if: "I only want to remove this mapped page from this lang tree AND not on other language tree". It would require to delete all and recreate all the others... not good. So it should at least be possible to "flag" if this page is mapped or not.

When a mapped page is moved within the language tree, the associated translations will be moved to the parent within their particular page tree, that is mapped to the new parent of the current languages page tree. But if you can have pages without a translation in the other language trees, what should happen on a page being moved to such unmapped page as new parent? Should this parent be replicated to the other language trees as new parent for the as well moved translations? Or should it be forbidden to move to unmapped parents?

I think it should be forbidden to move synced page to unmapped ones as parent. If parent is unmapped, all childs must be.

Maybe I just should reduce the functionalities to syncing the page trees 1:1 first.

Btw: What information on the current language is needed within the template? ISO-Code? LCID? Or what else? Let me know.

You mean a "$lang" var for use in templates,  I think ISO-codes 2 digit be the way to go...

Link to comment
Share on other sites

  • 5 weeks later...

After having lost focus on my sweet little module here, I’m back on it now. Stripping stuff to get it finally working including the most important functionality. And I start with a question again! ;)

$this->hooks['unpagemapPageOnDelete'] = $this->pages->addHookAfter("delete", $this, 'unpagemapPage');

The hook above is triggered when a page is deleted (not trashed, really deleted). But I’ve to deal with two different situations: The trash is emptied, so every page in it is deleted. As by moving a language page to trash its translations go there, too, I don’t need to care for them being deleted and unmapped.

But as soon as I open the edit page of a page in trash and delete it by using the "delete" tab, the page is deleted and I actually have to care for its translations. So I need something to check on and choose a way how to process the unmapping. I guess the best way is to check the process. Can I access the process’ name in the function hooked to the event above somehow like this?

    public function unpagemapPage($event) {
        $page = $event->argument[0];
        if($page->process != "ProcessPageTrash") { 
        …

Thanks in advance, again!

Link to comment
Share on other sites

Of course there is no reason. But there is the possibility to do it. And so I’ve to deal with the case someone uses the delete tab of the page edit form of a trashed page. Just to be sure the consistency of the page map won’t be corrupted.

Link to comment
Share on other sites

The first version won’t provide a possibility to exclude pages or parts of the language page trees from syncing. There already are methods and stuff included to implement it. I’ll also prepared the db tabels for it So it’s pretty sure, I’ll get it done for a later release.

There are several logical problems to be handled when unsynced pages are moved within a language’s page tree or synced once are moved into unsynced ones. I guess I can focus on it more clearly as soon as I got a basically functional version out and in use.

Link to comment
Share on other sites

Glad to hear you are working on this one again!

if($page->process != "ProcessPageTrash") {

The only page that will have that process is the actual Trash page. I think you are trying to detect this instead? (the current process being executed?)

if($this->process != 'ProcessPageTrash') {

However, I'm not totally sure that identifying whether the current Process is "ProcessPageTrash" is useful to you? It sounds like you are trying to detect someone manually deleting a page in the trash. I'm wondering if you might want to use $page->isTrash() instead? You can call isTrash() on any Page object, and it'll return true if the page is in the trash.

I think there's no reason to go delete a page manually in the trash? Just empty trash... ?

I agree with Soma that it may be accounting for something I wouldn't expect to be accounted for. If something is in the trash, I suppose I'd assume that it's not still being managed by any other systems. However, you are right that it is possible for someone to go and permanently delete a page in the trash without emptying the trash, so if it's a situation you think needs to be accounted for, I'm sure we can figure out how. I'm thinking that isTrash() may be what you were looking for, but let me know if not...

Link to comment
Share on other sites

Thanks for the inputs. The point is, that when a page from a language page tree is moved to trash, its translations are moved there, too. But maybe you guys are right. I should probably unmap the pages as soon as they leave their language’s page tree.

Link to comment
Share on other sites

  • 2 weeks later...

Hey, maybe thats a little bit out of context, but I would like to have a option like the one in TextPattern to add languages for the admin panel. They are using one central server for their translations and you can download the language file you like directly in your system out of the admin panel. That's a really great solution for adding multiple languages to the backend of an CMS.

Greets,

Nico

Link to comment
Share on other sites

  • 3 weeks later...

So, guys. Although I’m scared like hell I attached a first test version of the languages module to this post. It’s heavily cut down and removed a lot of the functionalities we discussed here. But the most of it is still in the code to implement it.

At this point, it just manages the mapping between language trees and leads the visitor to the default language.

Be warned: it’s still buggy. And there is a lot stuff it just doesn’t allow to be done. Like moving translated pages and stuff. Anyway: feel free to play around with it on your own risk. If you want to, have a look at the quick and dirty style code of an autodidact. I’d be more than happy to get some feedback and some hints to do the one or other thing in a better or at least cleaner way.

So, go fort it! :)

UPDATE: Attached file is out of date. Updated one here.

Link to comment
Share on other sites

Hi,

if I'm trying to edit "Home English" I'm getting this error:

Argument 1 passed to InputfieldWrapper::add() must be an instance of Inputfield, boolean given, called in /Applications/XAMPP/xamppfiles/htdocs/cms/extern/processwire/site/modules/ProcessLanguages.module on line 458 and defined (line 102 of /Applications/XAMPP/xamppfiles/htdocs/cms/extern/processwire/wire/core/InputfieldWrapper.php)

This error message was shown because you are logged in as a Superuser. Error has been logged.
Link to comment
Share on other sites

Do you have set any other language up, yet? I guess, it’s a problem with adding the language tab to the page edit form while there is just a single language. So the field may not be set up but the var passed to the add-method anyway. I’ll have a look.

Link to comment
Share on other sites

Glad to hear that.

In the page edit form of any page created within a language’s page tree, you should find a tab «Languages» at the top, left of «Delete» and «View». There are all languages – besides the one the currently edited page belongs to – listed with a link to the page’s translation, if available. If there is none, there is a select box to create a translation by cloning the current page or creating a blank page in the other language’s page tree.

There is no possibility to map an existing page of another language page tree manually to the currently edited page, yet.

Or did I miss your point?

Link to comment
Share on other sites

Oh, my fault. Didn't saw the "language" link at the top :)

But if I try to open /de/ or /en/ I'm getting the 404error page. The childs are working. And second question: Is there a way to get a link to the transition (like "$page->url->en" or so).

Greets,

Nico

Link to comment
Share on other sites

Sorry, another bug, I thought, I already had fixed. Seems I never finished that one. Ok, here’s the fix: On installation the module clones the root page’s template and copies the file in the template directory. But it misses the ".php". Go there, attach it, and your language’s start pages should be fine.

It’s fixed in the updated version. I attached the most recent version of the module to the first post of this thread.

I’m working on the template variable thing. There will be a variable $languages available with information the current language and of course ids and paths to the translations in the other languages. Yes, there is still a long way to go. :)

UPDATE: Template var is implemented. In all mapped pages there is the var $languages accessible. $languages->current stores an assoc array with data on the current language (id, language, code,...). $languages->translations stores an assoc array with the language codes as key and the translation page’s id as value. If there is no translation, the value is null.

Link to comment
Share on other sites

Thanks for your effort on this module. Unfortunately I'm too busy atm to check it out.

Just from reading, I'm not sure if you are aware of the multilanguage admin feature Ryan is working on for 2.2 (~end year) here: http://processwire.com/talk/index.php/topic,598.0.html

Not sure how this would take effect on your work here. May you want to make sure you could use some of what Ryan is implementing regarding new API stuff and such. Edit: just realized that this may not effect each other... not sure though if there could be some benefits.

Question:

One thing that just surprised me is why $Languages and not $languages, because it's like a constant?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...