# Independent page tree structure for every language

**URL:** <https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203>\
**Category:** Questions\
**Tags:** v2\
**Created:** [January 5, 2017, 9:56am UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203 "2017-01-05T09:56:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ola](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/ola/32/3465_2.png) [@ola](https://forum.getkirby.com/u/ola)\
**Post date:** [January 5, 2017, 9:56am UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/1 "2017-01-05T09:56:46Z")

</div>

I’m evaluating Kirby for an upcoming website that will be available in three languages. But as I understand, the default way that Kirby handles multi-language websites, is that there is only one page tree structure. That is, the default language is the master that defines the page tree structure. Then, each page can optionally be translated in other languages. If a page is missing a translated language, the default language is shown. This is what I understand is the default behavior of Kirby in a multi-language setup. Correct me if I’m wrong here.

This way to handle a multi-language site is not what my client want. The client wants an independent page tree structure for every language. For example they may want to have a specific page only available in the german version of the site. And another page only available in the swedish version of the site.

This is the prerequisites that the client has:

- The users should only need one login each, to access all language specific pages.
- Independent page tree structure for every language
- Possibility to choose the desired language version in the panel, to only show pages in that language.
- Possibility to create a new page in one language that is not shown in the other languages.
- Url:s in the form of sub folders: [example.com/de](http://example.com/de), [example.com/se](http://example.com/se), [example.com/en](http://example.com/en)

And for me as a developer, my prerequisites are these:

- One installation of Kirby.
- Blueprints should be translatable as usual.
- Formatting of dates and currencies should be handled according to current language both in backend and frontend.

Could someone point me in the right direction if this is possible?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 5, 2017, 11:36am UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/2 "2017-01-05T11:36:29Z")

</div>

> [@ola](#):
>
> But as I understand, the default way that Kirby handles multi-language websites, is that there is only one page tree structure. That is, the default language is the master that defines the page tree structure.

That is absolutely correct.

The only option to prevent this behavior I can think of, would be to use different folders for each language. But in that case, you would loose the language functions (translating blueprints, switching languages in the Panel etc.)

While you can use redirects and filters to prevent the default fallback behavior in a standard setup in the frontend, I don’t see a way to fulfill all your requirements, particularly [quote=“ola, post:1, topic:6203”]  
Possibility to choose the desired language version in the panel, to only show pages in that language.  
[/quote]

---

<div class="post-metadata">

**Author:** ![ola](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/ola/32/3465_2.png) [@ola](https://forum.getkirby.com/u/ola)\
**Post date:** [January 5, 2017, 12:03pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/3 "2017-01-05T12:03:48Z")

</div>

Would a possible solution be to use a multi-site setup somehow? Each site would then have a specific language specified. The only drawback would then be that there will be three different login for each author that needs access to all three language versions? In that case, that might be an acceptable drawback.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 5, 2017, 12:49pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/4 "2017-01-05T12:49:40Z")

</div>

That could in fact work, however, I’m not really familiar with multi-site setups.

---

<div class="post-metadata">

**Author:** ![ola](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/ola/32/3465_2.png) [@ola](https://forum.getkirby.com/u/ola)\
**Post date:** [January 5, 2017, 2:09pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/5 "2017-01-05T14:09:16Z")

</div>

I tried this multi-site setup but could not get it to work with different languages. But then again, I’m not that of an experienced Kirby developer yet. So I might have missed something essential.

Looks like I have to go back to WordPress for this project. 😢

---

<div class="post-metadata">

**Author:** ![lukasbestle](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lukasbestle/32/11437_2.png) [@lukasbestle](https://forum.getkirby.com/u/lukasbestle)\
**Post date:** [January 5, 2017, 3:08pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/6 "2017-01-05T15:08:46Z")

</div>

I don’t think you even need a multi-site setup for this. What about a directory structure like this:

```auto
content/
  de/
    language.txt
    ueber-uns/
      about.txt
  en/
    language.txt
    about-us/
      about.txt

```

Only one login, separate file structure, URLs are correct.  
The `language.txt` files would be used for global information that is normally placed inside `site.txt`.

This is a hack and probably more work than with the standard setup, but I think this could work.

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [January 5, 2017, 3:11pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/7 "2017-01-05T15:11:56Z")

</div>

But as I already mentioned above, with this kind of setup, you loose the language features, e.g. locale settings, blueprint translations, etc.

---

<div class="post-metadata">

**Author:** ![lukasbestle](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lukasbestle/32/11437_2.png) [@lukasbestle](https://forum.getkirby.com/u/lukasbestle)\
**Post date:** [January 5, 2017, 3:41pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/8 "2017-01-05T15:41:00Z")

</div>

Blueprint translations are still possible as they are based on the user language in the Panel, not the multilang feature.

Regarding locale settings etc.: Yes, definitely. But you can work around those, e.g. by getting the current language code from the URL in a plugin and setting custom options based on that.

---

<div class="post-metadata">

**Author:** ![ola](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/ola/32/3465_2.png) [@ola](https://forum.getkirby.com/u/ola)\
**Post date:** [January 5, 2017, 4:20pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/9 "2017-01-05T16:20:51Z")

</div>

Thanks @lukasbestle and @texnixe. I will definitely try this out. Yes it sounds like a hack, but a valid one. I will let you know how it went after I had a chance to experiment with this idea.

---

<div class="post-metadata">

**Author:** ![jenstornell](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/jenstornell/32/546_2.png) [@jenstornell](https://forum.getkirby.com/u/jenstornell)\
**Post date:** [January 5, 2017, 9:27pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/10 "2017-01-05T21:27:34Z")

</div>

Always nice to see other swedish people here! 🙂

**This is my take on it:**

Folder structure:

```nohighlight
sv
  all
  the
    swedish
  pages
de
  all
  the
    german
  pages

```

Then for the default language I would probably use a route to force a root url structure.

Then it would look like this:

```nohighlight
example.com
example.com/the
example.com/the/swedish

example.com/de
example.com/de/the
example.com/de/the/german

```

When using WordPress back in the old days, I solved many sites the similar way and I think it’s fine.

Maybe that’s already suggested by @texnixe or @lukasbestle.

However, I also saw your suggestion in this topic, but from my point of view Kirby can already handle this case well enough.

---

<div class="post-metadata">

**Author:** ![lukasbestle](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lukasbestle/32/11437_2.png) [@lukasbestle](https://forum.getkirby.com/u/lukasbestle)\
**Post date:** [January 5, 2017, 9:35pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/11 "2017-01-05T21:35:45Z")

</div>

Yep, that’s exactly what I meant above. 🙂

---

<div class="post-metadata">

**Author:** ![ola](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/ola/32/3465_2.png) [@ola](https://forum.getkirby.com/u/ola)\
**Post date:** [January 9, 2017, 2:36pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/12 "2017-01-09T14:36:30Z")

</div>

Ja det är alltid trevligt med lite svenskar @jenstornell 🙂

Thanks for all help here. I have played around a little with this and got a working solution. As you suggested I have a directory structure with a root page for all languages.

The problem I encountered was that I was unable to use the [custom language variables](https://getkirby.com/docs/languages/variables) for string translations. This needed the multi language mode to be activated, which I don’t wanted in the first place. But in the source code I found the code that loaded these language files, so I copied them to my `site.php` file and loaded them manually.

After writing some code that extracts the language code from the url, my `site.php` looks like this:

```php
<?php 

$kirby = kirby();

// Map of languages used:
$languages = array(
	'en' => 'en_US',
	'de' => 'de_DE',
	'sv' => 'sv_SE'
);

// Get paths from url:
$paths = str::split($kirby->path, '/');

// Extract possible language code from first path. I.e: 'en' from www.example.com/en/another/page
if (count($paths) && isset($languages[$paths[0]])) {
	$language = $paths[0];
} else {
	$language = 'sv'; // Fallback language
}

// Path for the language file:
$path = $kirby->roots()->languages() . DS . $language;

// Load .php file if it exists:
if(f::exists($path . '.php')) include_once($path . '.php');

// Load .yml file and set as language variables if it exists:
if(f::exists($path . '.yml')) l::set(data::read($path . '.yml', 'yaml'));

// Set correct locale for php date and time functions:
setlocale(LC_ALL, $languages[$language]);

```

This works. But please correct me if I did something wrong or if it’s possible to simplify this even more.

---

<div class="post-metadata">

**Author:** ![jenstornell](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/jenstornell/32/546_2.png) [@jenstornell](https://forum.getkirby.com/u/jenstornell)\
**Post date:** [January 10, 2017, 7:38am UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/13 "2017-01-10T07:38:19Z")

</div>

I guess that language variables are not loaded at all on a single language installation. Therefor you need to do it yourself like you did. If this works I don’t find anything wrong with that.

Personally I would try to wrap it up as a plugin. I have not tested but in my mind this might work:

1. Copy the code you have to like `plugins/my-plugin/my-plugin.php`.
2. Add this to your site.php file: `kirby()->plugin('my-plugin');`

If it works it will force load your plugin before other things are loaded. It will run only once even if you force load it like this.

As I said, it’s untested but if it works it would be a “nice” hack. 🙂

---

<div class="post-metadata">

**Author:** ![lukasbestle](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lukasbestle/32/11437_2.png) [@lukasbestle](https://forum.getkirby.com/u/lukasbestle)\
**Post date:** [January 10, 2017, 12:33pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/14 "2017-01-10T12:33:51Z")

</div>

> [@jenstornell](#):
>
> If it works it will force load your plugin before other things are loaded.

As I wrote before, you shouldn’t do this. If you force load a single plugin before the plugins get loaded by Kirby, the other plugins won’t get loaded automatically anymore. Force loading just works to load in dependencies from plugins.

---

<div class="post-metadata">

**Author:** ![jenstornell](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/jenstornell/32/546_2.png) [@jenstornell](https://forum.getkirby.com/u/jenstornell)\
**Post date:** [January 10, 2017, 12:36pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/15 "2017-01-10T12:36:21Z")

</div>

Oh, I forgot about that. 🙂 Maybe just keep it like it is then, or use `include` instead, maybe to a file outside the plugin folder somewhere.

---

<div class="post-metadata">

**Author:** ![lukasbestle](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/lukasbestle/32/11437_2.png) [@lukasbestle](https://forum.getkirby.com/u/lukasbestle)\
**Post date:** [January 10, 2017, 12:57pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/16 "2017-01-10T12:57:21Z")

</div>

Once we have support for the language registry, loading language files in single-language sites will work out of the box anyway. 🙂

---

<div class="post-metadata">

**Author:** ![kris](https://avatars.discourse-cdn.com/v4/letter/k/82dd89/32.png) [@kris](https://forum.getkirby.com/u/kris)\
**Post date:** [January 13, 2017, 11:51am UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/17 "2017-01-13T11:51:44Z")

</div>

It seems to me that [Ola](https://forum.getkirby.com/users/ola) problem is pretty related to [another topic](https://forum.getkirby.com/t/default-template-problem-on-multilingual-website-since-kirby-2-3/5118) awaiting Kirby 2.5 to be solved. Once it’s solved, there will be no need for hacks. Ola would be able to use the same structure for all langauges, benefits from all nice language features, and filter menu/contents by language as it was possible before Kirby 2.3. What is not translated will be ignored in other languages.  
The actual problem is that Kirby requieres the default language .txt file to be present in each page’s folder to work correctly. Free us from this constraint, and everything would become easy.

---

<div class="post-metadata">

**Author:** ![dennisb](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/dennisb/32/11676_2.png) [@dennisb](https://forum.getkirby.com/u/dennisb)\
**Post date:** [December 1, 2017, 4:03pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/18 "2017-12-01T16:03:01Z")

</div>

this topic is nearly one year old, and i stumpled upon it, while looking for how to have a multilang-site with independent pages/page trees per language.  
is this still best practice?

---

<div class="post-metadata">

**Author:** ![texnixe](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/texnixe/32/5754_2.png) [@texnixe](https://forum.getkirby.com/u/texnixe)\
**Post date:** [December 1, 2017, 4:23pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/19 "2017-12-01T16:23:22Z")

</div>

Well, the way multi-languages sites work hasn’t changed, so I think this is still the easiest way to achieve this.

---

<div class="post-metadata">

**Author:** ![distantnative](https://dub1.discourse-cdn.com/flex017/user_avatar/forum.getkirby.com/distantnative/32/11319_2.png) [@distantnative](https://forum.getkirby.com/u/distantnative)\
**Post date:** [February 6, 2025, 5:30pm UTC](https://forum.getkirby.com/t/independent-page-tree-structure-for-every-language/6203/20 "2025-02-06T17:30:23Z")

</div>


