PhileCMS / Phile

A flat file CMS with a swappable parser and template engine.
https://philecms.github.io/
Other
256 stars 48 forks source link

Multilingual Site #300

Closed MrTopom closed 6 years ago

MrTopom commented 8 years ago

Hello,

I started using PhileCMS and I want a multilingual site. So I read the old issue related to it and tried to get some ideas and solution from it.

I want to have in my content folder, the language in the file name : home.en.md BUT I want to keep the language at the beginning of the URL : en/home

First Question

So I started to look in and see that I should create a Router class that would make the transformation from the URL to the corresponding file name. But for that I need to modify the index to set this router instance, replacing the default one. Would there be a better solution to replace the router instance ?

Second Question

When this routing was working I then decided to modify also the menu of the site, to display only pages that are with this language AND need to be in the menu. The language is stored in Session and I added a meta key to the files 'is_in_menu', to have them visible in the menu. Again this needs to modify the template to make the good filtering with new twig functions, any other ideas ?

I'll add the flags to switch language dynamically tomorrow.

Regards Arnaud

Schlaefer commented 6 years ago

Filtering with twig functions seems like a good idea. Working with the Router sounds good on the surface, but I imagine it becomes a hassle fast because you have to meddle with the core? It's easier to just swap the right page in using the after_resolve_page event. Here's a basic Plugin implementation I would start with:

class Plugin extends \Phile\Plugin\AbstractPlugin
{
    protected $events = [
        'after_resolve_page' => 'servePage',
        'template_engine_registered' => 'setTemplateFct'
    ];

    protected $lang;

    public function servePage($data = null)
    {
        $pageId = $data['pageId'];
        list($lang, $pageId) = explode('/', $pageId, 2);
        $this->lang = $lang;

        $pageId = $pageId ?: 'index';
        $pageId = $pageId . '.' . $this->lang;

        $repository = new \Phile\Repository\Page();
        $data['page'] = $repository->findByPath($pageId);
    }

    public function setTemplateFct($data)
    {
        $languageFilter = new \Twig_SimpleFilter('languageFix', function ($url){
                list($url, $lang) = explode('.', $url, 2);
                if ($this->lang !== $lang) {
                    return false;
                }
                return $lang . '/' . $url;
    });
        $data['engine']->addFilter($languageFilter);
    }

}

in the template:

{% for page in pages %}
        {% if page.url | languageFix %}
          <li><a href="{{ page.url | languageFix }}">{{ page.title }}</a></li>
        {% endif %}
{% endfor %}