BoltTranslate / Translate

Provides translation for contenttypes.
Other
43 stars 37 forks source link

[BUG] Fieldtype block translation always uses values from the bolt_field_value table #171

Closed SanderOnline closed 6 years ago

SanderOnline commented 6 years ago

I'm trying to use the Translate extension in combination with the fieldtype block but i'm having some issues to get it working and keep getting the same error.

Details

Reproduction

I have a contenttype Pages with some dynamic nodes for the different contentblocks (getting the same errors if i don't use the nodes way):

pages:
    name: Paginas
    singular_name: Pagina
    fields:
        title:
            type: text
            label: Paginatitel
            class: large
            required: true
            translatable: true
            group: Eigenschappen            
        locale:
            type: locale            
        slug:
            type: slug
            uses: title
        teaser:
            type: html
            height: 150px
            prefix: 'Introductietekst die getoond wordt onder de titel en bij de zoekresultaten'            
            translatable: true
        image:
            group: Header afbeelding
            type: image
            label: Header afbeelding
            upload: headers      
            prefix: 'Ideale formaat is 1920 pixels breed en 500 pixels hoog, andere formaten worden afgesneden om het passend te maken'
        contentblocks:
            type: block
            label: Content blokken
            group: Pagina content
            translatable: true
            fields:            
                <<: *textsection
                <<: *textsectionlayout
                <<: *videosection
                <<: *videosectionlayout
                <<: *bigimagesection
                <<: *bigimagetextsection
                <<: *blogsection
                <<: *quotesection
                <<: *reviewsection
                <<: *buttonssection               
        seo:
            type: seo
            group: "SEO instellingen"   
        template:
            type: templateselect 
        nldata:
            type: hidden
        nlslug:
            type: locale_data
            index: true
        dedata:
            type: hidden
        deslug:
            type: locale_data
            index: true                                              
    default_status: published
    recordsperpage: 30
    icon_many: "fa:file"
    icon_one: "fa:file"     

When i make a new page (standard in Dutch) and fill it with data the page shows and works. Now when i add a translation, in this case German, and save it, it always shows the Dutch translations for the block field values. All the other values like title, teaser etc work fine it only happens with the fields inside the block fieldtype.

When i look in the database the German block values are added to the record:

record_data

Then when looking in the bolt_field_value table the Dutch translation is there (i'm guessing this is how it is supposed to save the data):

repeater_data

When getting the data of the "textsection" I tried both following ways:

{{ item.content }}      
{{ item.get('content') }}

But both give the same result: the Dutch translation saved in the bolt_field_value table.

Also, after i saved the German data in the adminpanel and switch back to Dutch nothing strange happens but when i then switch back to German i get the error message below and i'm stuck on this error even if i remove the translatable: true in my contentblocks node.

page_error

Not sure if i did something wrong or fieldtype:block isn't supported at the moment. Hope the issue is clear, if you need more information just let me know.

denis-gorin commented 6 years ago

hi, i've had same issue this workaround helps me (unfortunately it is a core hack)

file: vendor\bolt\bolt\src\Storage\Field\Type\RepeaterType.php line: 190 find:

// This block separately handles JSON content for Templatefields
if (isset($data[$key]) && Json::test($data[$key])) {
... TO BE REMOVED ...
}

replace with:

if (isset($data[$key]) && Json::test($data[$key])) {

    if (isset($this->mapping['fields'])) {
        $originalMapping[$key]['fields'] = $this->mapping['fields'];
        $originalMapping[$key]['type'] = 'repeater';
    } else {
        $originalMapping[$key]['fields'] = $this->mapping['data']['fields'];
        $originalMapping[$key]['type'] = 'block';
    }

    $mapping = $this->em->getMapper()->getRepeaterMapping($originalMapping);

    $decoded = Json::parse($data[$key]);
    $collection = new RepeatingFieldCollection($this->em, $mapping);
    $collection->setName($key);

    if (isset($this->mapping['fields'])) {
        if (isset($decoded) && count($decoded)) {
            foreach ($decoded as $group => $repdata) {
                $collection->addFromArray($repdata, $group);
            }
        }
    } else { 
        if (isset($decoded) && count($decoded)) {
            foreach ($decoded as $group => $block) {
                foreach ($block as $blockName => $fields) {
                    if (is_array($fields)) {
                        $collection->addFromArray($fields, $group, $entity, $blockName);
                    }
                }
            }
        }
    }

    $this->set($entity, $collection);

    return;
}

file: extensions\vendor\animal\translate\src\Storage\Legacy.php line: 115

add before:

if (isset($contentType['fields'][$key]) && $contentType['fields'][$key]['type'] === 'block'  && $value !== null) {
    $originalMapping=[];
    $originalMapping[$key]['fields'] = $contentType['fields'][$key]['fields'];
    $originalMapping[$key]['type'] = 'block';
    $mapping = $app['storage.metadata']->getRepeaterMapping($originalMapping);
    $record[$key] = new RepeatingFieldCollection($app['storage'], $mapping);
    foreach ($value as $group => $block) {
        foreach ($block as $blockName => $fields) {
            if (is_array($fields)) {
                $record[$key]->addFromArray($fields, $group, null, $blockName);
            }
        }
    }
}
SanderOnline commented 6 years ago

Hi @denis-gorin ,

Thanks so much for your workaround, it seems to work fine when i use your code. Really appreciated!

SvanteRichter commented 6 years ago

I'd be happy to accept a PR that makes this work as long as it's stable. For now though blocks aren't supported in translate, so I'm going to close this.