magda

Hi all, I am using fluent on ss4 and I wonder if someone has a nice solution for translated objects. Right now, I cant figure out very easy, if an object is already translated. Another example is if I delete an object in one language, it does not disappear, because it's still there in another language. That confuses some customers.. hope you know what I mean.. any ideas?

robbieaverill

hey magda - re figuring out if an object is translated (in a particular locale) you can use existsInLocale(), isDraftedInLocale() and isPublishedInLocale() from the fluent extensions.

re objects and deleting, tractorcow recently added a more sophisticated delete policy, you may want to use the latest version of fluent if you aren't already

👍 (1)
wmk

And you can afaik use a "fluent filter" to only get objects in your current locale, see https://github.com/tractorcow-farm/silverstripe-fluent/blob/master/docs/en/scenarios.md#solution-one---filtered-locales-extension

Show 1 attachment(s)
GitHub  
tractorcow-farm/silverstripe-fluent

Multi-language translate module for Silverstripe, without having to manage separate site trees. - tractorcow-farm/silverstripe-fluent

Hide attachment content
magda

Is it possible to open a redirector Page in a new tab?

magda

hey 🙂 can you recommend any yaml-parser for silverstripe 4? in silverstripe 3 I used sfYamlParser like this

  1. require_once 'thirdparty/zend_translate_railsyaml/library/Translate/Adapter/thirdparty/sfYaml/lib/sfYamlParser.php';
  2. $parser = new sfYamlParser();
  3. $fileContents = str_replace( [
  4. "\r\n",
  5. "\r"
  6. ], "\n", file_get_contents( Director::baseFolder() . '/mysite/_config/data.yml' ) );
  7.  
  8. self::$data = $parser->parse( $fileContents );
magda

@wmk ahhh, thanks.. and how do I get the current <theme-name> ?

magda

Hi there, I have an email template and want to add an image of my themes-folder. Unfortunately the link $ThemeDir/images/header.png is not working because the $ThemeDir links to /silverstripe/admin/themes/cms-forms . When I use $ThemeDir inside my ThemesFolder, the link is correct /resources/themes/default Am I missing something? In some other Projects it's working fine

magda

Hey I am using fluent on my site. I have a translatable Model which has_one File Is it possible to link different Files for the different languages? (would be dumb if user get a spanish file, when they requested one in english)

(1)
blueo

yeah with has one you can localise the MyFileID field and that will let you attach a different ID per locale

👍 (2)
wmk

Docs for that are a bit hidden: https://github.com/tractorcow-farm/silverstripe-fluent/blob/master/docs/en/configuration.md#field-localisation-configuration

Show 1 attachment(s)
docs/en/configuration.md

# Configuration

Most configuration is done via the CMS locales section.

Please make sure to REMOVE any `i18n::set_locale` calls from your `_config.php` file, as it
will interfere with locale bootstrapping in certain situations (such as `Security` controller actions).

## Locale configuration

You can create locales via the `/admin/locales` CMS section. 

Each locale has these fields in the CMS editor:
 - `Locale`: Dropdown which lets you select a locale code from the global locale source
 - `Title`: Name to use for this locale in the locale switcher
 - `URL Segment`: Defaults to the locale (e.g. `en_NZ`) but can be customised. Must be unique.

Check the box titled `This is the global default locale` to set this locale as the global default. 

**Note:** If using domains, you can additionally assign per-domain defaults as well.

 - `Domain`: Dropdown to assign this locale to a domain.

Navigate to the `Fallbacks` tab, which allows you to specify one or more fallback locales for this locale.

Once you add at least two locales to your site, you can begin localising your content. 

_**Important:** Pages in locales that fall back must be added and published in each locale you want them to be visible 
in - including the default locale. This essentially requires the re-publication of content in each locale, once content 
is localised. Be aware that the site will not appear as it did before the creation of Fluent locales until this step is 
completed._

If desired, Fluent can be enabled on a field by field basis. Note that non-translated fields on any page will be 
displayed in the default locale.

## Default locale options

### Disable default locale url segment prefix

`TractorCow\Fluent\Extension\FluentDirectorExtension.disable_default_prefix` (default: `false`)

If you prefer to keep the prefix off from all links in the default locale, you can set this option via
YML config. When this is enabled, the prefix will only be used (prepended) in links to non-default locales.

E.g.

```yaml
---
Name: myfluentconfig
---
TractorCow\Fluent\Extension\FluentDirectorExtension:
  disable_default_prefix: true

If this is left at the default, false, then the prefix will only be omitted for the home page for the default locale, instead of all pages.

It is recommended to leave this on in order to ensure the correct locale is set for every page, but in some cases (especially when upgrading websites) it may be better to keep existing urls for the default locale intact.

Field localisation configuration

Great, now we've set up our languages. Our next job is to decide which DataObjects, and which fields of those DataObjects, should be localised.

By default Fluent will attempt to analyse the field type and name of each DBField specified in your DataObject. Rules specified by the below configurations can be used to determine if a field should be included or excluded, either by name, or by type (in order of priority):

  • TractorCow\Fluent\Extension\FluentExtension.field_exclude Exclude by name
  • TractorCow\Fluent\Extension\FluentExtension.field_include Include by name
  • TractorCow\Fluent\Extension\FluentExtension.data_exclude Exclude by type
  • TractorCow\Fluent\Extension\FluentExtension.data_include Include by type

E.g.

---
Name: fluentfieldconfig
---
TractorCow\Fluent\Extension\FluentExtension:
  data_exclude:
    - Varchar(100)
    - DBHTMLText

Fields can also be filtered directly by name by using the translate config option, set to the fields you want localised. Note that this must be on the same class as the database field is specified (not subclasses).

---
Name: myblogconfig
---
Page:
  translate:
    - 'Heading'
    - 'Description'

or via PHP

use SilverStripe\CMS\Model\SiteTree;

class Page extends SiteTree
{
    private static $db = [
        'Heading'     =&gt; 'Varchar(255)',
        'Description' =&gt; 'Text',
        'MetaNotes'   =&gt; 'Text',
    ];

    private static $translate = [
        'Heading',
        'Description'
    ];
}

In the above example, Heading and Description will be translated but not MetaNotes.

If you want to localise a has_one relation then you can add the field (with 'ID' suffix included).

BlogHolder:
  translate:
    - 'OwnerID'

Note: If you wish to translate has_many or many_many then those objects will need to be filtered via another method. See Locale based filter configuration.

If you want to localise a DataObject that doesn't extend SiteTree then you'll need to add the appropriate extension:

---
Name: myextensions
---
MyDataObject:
  extensions:
    - 'TractorCow\Fluent\Extension\FluentExtension'

If MyDataObject is versioned, use FluentVersionedExtension instead and apply this config after the Versioned extension using an after block in your config title block.

---
Name: myextensions
after: '#versionedfiles'
---
MyDataObject:
  extensions:
    - 'TractorCow\Fluent\Extension\FluentVersionedExtension'

Set the translate option to 'none' to disable all translation on that DataObject.

class FormPage extends Page
{
    private static $translate = 'none';
}

Note: Editing any locale affects the SiteTree(_live) table. In contrast to SilverStripe 3, the SiteTree table is only used for non-localised fields.

Frontend publish required

By default, DataObjects must be Localised in order for them to be viewed on the frontend. In the case of a SiteTree record, this means that there must be a SiteTree_Localised row for this record and Locale to view the page in stage=Stage, and there must be a SiteTree_Localised_Live row for this record and Locale to view the page in stage=Live.

We can change this behaviour by updating the frontend_publish_required configuration.

Globally:

TractorCow\Fluent\Extension\FluentExtension:
  frontend_publish_required: false

For a specific DataObject:

MySite\Model\MyModel:
  frontend_publish_required: false

Note: If you are applying this via an Extension, be sure to apply it after the FluentExtension.

The result is that a DataObject that has not been Localised, will display on the frontend with content populated by it's Fallbacks (the same beheviour as what you see when viewing DataObjects from within the CMS).

Locale based filter configuration

In addition to localising fields within a DataObject, a filter can also be applied with the TractorCow\Fluent\Extension\FluentFilteredExtension extension to conditionally show or hide DataObjects within specific locales. This will create a many_many relationship between your object and the locales table.

This feature is also necessary in cases where has_many or many_many relationships will need to be customised for each locale. For example, this could be applied to a Product with limited availability in other countries.

Note: It's not necessary to actually localise this object in order for it to be filterable; FluentFilteredExtension and FluentExtension each work independently.

Warning: This must be added to the base class, such as SiteTree in order for it to filter for pages, or for queries of that base type.

---
Name: myproductconfiguration
---
Product:
  extensions:
    - 'TractorCow\Fluent\Extension\FluentFilteredExtension'

Make sure that if (and only if) you are filtering a DataObject that doesn't call the default field scaffolder (such as by calling parent::getCMSFields()), make sure that your code calls extend('updateCMSFields', $fields) as demonstrated below.

public function getCMSFields()
{
    $fields = new FieldList(
        new TextField('Title', 'Title', null, 255)
    );
    $this-&gt;extend('updateCMSFields', $fields);
    return $fields;
}

Now, when editing this item in the CMS, there will be a gridfield where you can assign visible locales for this object.

![Locale Filter]…

Hide attachment content
wmk

>If you want to localise a has_one relation then you can add the field (with 'ID' suffix included).

  1. BlogHolder:
  2. translate:
  3. - 'OwnerID'
magda

yes, the Model is managed in a ModelAdmin. I need the Link in a Controller (should send an email with the edit link)