Jump to content

Where to hook to override language to output for field


BitPoet
 Share

Recommended Posts

I'm a bit at a loss where to put my hooks. My requirement is to have a checkbox in the page (already there) that tells my module to pull fields (i.e. body, headline etc., but possibly others too in the near future) from the default language, no matter if there's a value set in the current language, and apply some replacement before rendering (think HannaCode-like, though with a whole dictionary database for technical terms behind it).

Now, I'm unsure where to hook. I've looked through the LanguageSupport modules and tried to spy in HannaCode, but I've not been able to wrap my head around all the getLanguage..., getFormatted... and whatnot hookable methods involved. Attempts at overriding LanguageSupportFIelds::hookFieldtypeFormatValue and extending its logic somehow ended up with an endless recursion. If anybody could give me a few pointers (or method names) I should look for, this would be great.

Link to comment
Share on other sites

Thank you! That was exactly the place. I had to fiddle a bit because I tried at first with $page->getLanguageValue which again led to an infinite recursion, but this works:

    public function init() {
        $this->addHookBefore('FieldtypeText::formatValue', $this, 'hookBeforeFormatValue');
    }

    public function hookBeforeFormatValue($event)
    {
        $page = $event->arguments(0);
        $field = $event->arguments(1);
        $value = $event->arguments(2);

        if( $field->name == 'body' && $page->isMultiLang == 1 && ! $this->user->language->isDefault() )
        {
            $lang = $this->user->language;
            $this->user->language = wire('languages')->get('default');
            $value = $page->get($field->name);
            $this->user->language = $lang;
            // Pattern replacement part comes here
            $event->return = $value;
            $event->replace = true;
        }
    }

I've thought about making the valid field names configurable in the template definition, but that's probably a bit too steep right now. Thanks again!

Link to comment
Share on other sites

Huh. My enthusiasm was premature. Unfortunately, this only works if I don't need to modify the text value in the default language. If I try to do the latter, I once again end up in an infinite recursion.

I tried to move the default language replacement part into a textformatter, but then the value gets replaced with the original one again. I'm at a loss.

Link to comment
Share on other sites

The recursion happens cause you get the field from pagr which triggers formatValue again. Maybe it's better to get the unformatted value getUnformatted(field) that will get the object with the languages inside or prevent recursion with a marker you set to the page to ignore them. Maybe also a after hook works better as there might be the language module song theit work too. Or set hook to after those of the language modules.

I'm still not sure what exactly you try to do and why.

Link to comment
Share on other sites

I'm still not sure what exactly you try to do and why.

Basically, I've got migrated articles in multiple languages. The body text in the default language (German) contains translation tags in the form of "{TR:Teil}: xxx.yyy.zzz - {TR:Gehäuse}". These TR tags need to be read, the text extracted, translated and  replaced (or, if accessed in the default language, just the tags stripped) so the page displays "part: xxx.yyy.zzz - housing" for English and "Teil: xxx.yyy.zzz -Gehäuse" for German.

There may be a body text in English as well, so relying on the "use text from default language if empty" feature is unfortunately not sufficient.

Link to comment
Share on other sites

Why don't you just build a textformatter instead of fiddling around with some hooks? These can be very simple compared to what the hanna code module looks like. Here is one I build recently: http://pastebin.com/Tc1sHvD2. I just don't know if this will play well with your vision of mixing and matching language fields with your own translation stuff. I can't really see, how you want this to work, as it seems like this stuff "{TR:Teil}: xxx.yyy.zzz - {TR:Gehäuse}" shouldn't be part of each language's text, but still kinda be part of each one.

Link to comment
Share on other sites

Thank you both, Soma and LostKobrakai. Textformatter and getUnformatted in combination were what I was missing! Here's the working code - short and to the point:

    public function formatValue(Page $page, Field $field, &$value)
    {
        if( $page->isMultiLang == 1 )
        {
            if( $this->user->language != 'default' )
            {
                $value = $page->getUnformatted($field->name)->getDefaultValue();
            }
            $value = preg_replace_callback('/\{TR:([^}]+)\}/', array($this, "translate"), $value);
        }
    }

  • Like 1
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

×
×
  • Create New...