When using metatags, the Dublin Core defaults are normally set to
[node:language]
which produces
<meta property="dcterms.language" content="en" />
... all the time. No matter what translated version we are viewing.

I could not find in the token browser anything looking like [node:entity_translation:language], and would have hoped that just the [node:language] would have been updated anyway.

Is this a feature request or is there a setting I've missed to make this happen?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

dman’s picture

Meta tags
7.x-1.0-beta4

Token
7.x-1.4

Entity Translation
7.x-1.0-beta2

Using cookie-based language switcher.

plach’s picture

Category: support » feature

This is a feature request: we should expose a token returning the current translation language.

dman’s picture

Component: Documentation » Base system

Thanks for the update. I've been making excuses to the client (an child health support agency trying to publish information to minority families) for a while now about why their translation tester are bringing up invalid results.

I'm willing and able to help on this, but not sure where to start yet.

As in my OP, I'd *prefer* if the normal [node:language] was updated to reflect the content as expected rather than introduce a new token that would create a conflict.

plach’s picture

I'm willing and able to help on this, but not sure where to start yet.

I think defining a token that just calls entity_language() should be enough.

As in my OP, I'd *prefer* if the normal [node:language] was updated to reflect the content as expected rather than introduce a new token that would create a conflict.

Nope, this would break all the cases where you want the actual node language (besides working only with nodes).

plach’s picture

Version: 7.x-1.0-beta2 » 7.x-1.x-dev

Sorry, the previous suggestion was wrong: we should call entity_translation_form_language() instead of entity_language().

dman’s picture

I'm starting this.
Looking at the current -dev, I see

/**
 * @deprecated This is no longer used and will be removed in the first stable
 *   release.
 */
function entity_translation_form_language($langcode, $handler) {

I found that the information on the current translation was not available in the provided $data['entity'] ($node) at token time, but it was easily already present in the tokens $options array, so I grabbed it direct from there.

A also discovered that with entity_translation, all the meta tags (DC) are unique to each translation. This ... makes sense in most cases I guess. :-/
However, given that the dcterms:description and title etc, - including the language-specific URL - is overridden to the appropriate language (correctly) already - it really does seem to make the case for the [node:language] to be modified directly to match it.

As it is, with my current work-in-progress I can modify my settings (and have to now change all my existing content) to use the new token (name?) [node:entity_translation]
( 'node' is a stand-in for whatever entity type is used, not locked to 'node'. )

Current behavior, with meta tags configured, using 'title.module' which also seems to do come corrections to the tokens.

dcterms:title [node:title]
dcterms:description [node:summary]
dcterms.language [node:language]
dcterms.identifier [current-page:url:absolute]

Produces the *wrong*

<meta property="dcterms:title" content="O se Fa‘asusu lelei" />
<meta property="dcterms:description" content="O le tu‘uina lelei o le susu i le gutu o lau pepe o le ki lea i le lelei o le fa‘asusuina ia te oe." />
<meta property="dcterms.language" content="en" />
<meta property="dcterms.identifier" content="http://kidshealth.gizmo:8082/o-se-fa%E2%80%98asusu-lelei" />

If entity-translation is prepared to overwrite the [node:title], [node:description] and hard-reference the translated URL - *I think* it should be honest about the [node:language] it's using to do so.

I've got code now that does both, and you can use either.
Patch soon.

dman’s picture

Status: Active » Needs review
FileSize
1.86 KB

This just uses hook_tokens_alter to repair the core :language value

dman’s picture

This alternative provides a unique token [x:entity_translation_language] that exposes the language key

plach’s picture

However, given that the dcterms:description and title etc, - including the language-specific URL - is overridden to the appropriate language (correctly) already - it really does seem to make the case for the [node:language] to be modified directly to match it.

No, this won't work: you'd be overwriting the actual entity language. How would you know it then? What you are looking for is the language of the entity translation being displayed, so we need a new token returning it.

#8 is not viable for the reasons above, #9 makes sense and might work in your case depending on what language value is passed by the calling code. However it should be labelled differentely, something like active_language.

If you wish to expose a token labelled entity_translation_language, it should hold the value returned by entity_translation_get_existing_language(), instead of entity_translation_form_language() (sorry, I forgot about the renaming).

plach’s picture

Status: Needs review » Needs work
plach’s picture

Probably the best thing to do would be:

<?php
$replacements[$original] = entity_translation_get_existing_language($options['language']->language);
?>
dman’s picture

Based on current working behavior, used in node_tokens() and the given first-case ecample of hook_tokens_alter

I find it hard to imagine that:

[node:title] = "O se Fa‘asusu lelei"
[node:summary] = "O le tu‘uina lelei o le susu i le gutu o lau pepe o le ki lea i le lelei o le fa‘asusuina ia te oe."
[node:language] = "en"

could be seen as "by design". It's false.

If you have a reason to need the 'original' language (ie, not the one that is actually being used, or the one that is being displayed, or the one that the user or the developer wants right now, and not necessarily unique or original) - then that can be retrieved from the entity still. I'm not overwriting the "actual entity language" I'm returning as a usable token what entity language is currently active when the context/options for the token request say "we are showing this language"

The primary language you want to define to the user, the browser, the search engine and the designer ... and the rest of Drupal that cares in most places ...is the one being used right now.

What are we missing about the real-world here?

plach’s picture

[node:language] maps to $node->language (via entity_language()), that is the node primary language (the one you enter in the language selector). Changing the value returned by the token to a contextual value means changing its meaning, which will cause troubles in any place where that token is used with its original meaning. I won't commit anything going this way, sorry.

dman’s picture

I understand your position, and I'm totally OK with your idea of just adding an alternative token as a compromise for now. That is certainly the least disruptive given where we are right now, and what people are currently expecting to have to work around.

To agree with you, It seems to me (and my editors) that the language they select "in the language selector" when they create a translation - precisely as you say - would be the one that should be used when that translation is being used.
The Samoan translation of this entity is in language:Samoan.

The same argument you make about mapping says that
[node:title] should only be the $node->title in the node primary language and should not change based on the "context". I sorta hear your point at a data-integrity level, but that's not actually what core does - core currently does modify the token and provides the appropriate [node:title] for the context it is being requested in. It seems fair that the language tag that accompanies and identifies that translation changes with it.
I find it pleasantly correct that when I retrieve the [node:title] I get the one that is contextually more accurate.

If you are claiming that the existing core and title.module behavior is currently meaningfully wrong ... That is totally possible - it's probably a discussion to be had by folk more experienced in translation than I am. But I do feel that what they do currently is more intuitively expected and useful. I was happy that they automatically did "the right thing" out of the box. And I was thinking to move into line with that. As illustrated by (what I see as a contradiction) in #13.

I would have said that a page rendering markup as

<html lang="de" >
<title>プレミアムドメイン</title>

would be incorrect on the face of it. So I must be missing something about how this is expected to behave.

We can just go forward with the additional custom token - at least that gives the implementers the choice.

Sorry, part of my resistance is that I would now have to run some sort of retroactive bulk rewrite on our existing corpus of content to rewrite the currently-saved meta-tokens from the system-default of x:language to a new x:entity-language . I know the actual name of the new token would need work...

plach’s picture

To agree with you, It seems to me (and my editors) that the language they select "in the language selector" when they create a translation - precisely as you say - would be the one that should be used when that translation is being used.

There is no language selector when entering a translation, it only shows you the original language ($node->language) :)

The same argument you make about mapping says that [node:title] should only be the $node->title

Here we are talking about a translatable field, which is expected to change value depending on context. The language property is not translatable, it has the same value for all languages, exactly because it indicates the original language.

Anyway whether I agree or not with this statement is irrelevant, since what concerns me is changing an existing behavior.

I would have said that a page rendering markup as

プレミアムドメイン
would be incorrect on the face of it.

Undoubtly, but the reason it's incorrect is that a token holding the original language is being used to generate markup requiring the current language.

We can just go forward with the additional custom token - at least that gives the implementers the choice.

Exactly, the whole point is giving site builders the ability to pick the language they need based on their specific requirements.

Sorry, part of my resistance is that I would now have to run some sort of retroactive bulk rewrite on our existing corpus of content to rewrite the currently-saved meta-tokens from the system-default of x:language to a new x:entity-language.

I understand this may be a problem, but we can't screw many sites out there to solve this particular case :)
I'd suggest you to rewrite the value of [node:language] from a custom module on your site.

I know the actual name of the new token would need work...

If you are still interested in providing a patch for the new token I'd probably go for [x:translation-language].

dman’s picture

Here we are talking about a translatable field, which is expected to change value depending on context. The language property is not translatable, it has the same value for all languages, exactly because it indicates the original language.

This makes the point you are making clearer to me. Thanks.

I was - from a site building point of view - used to imagining a page template as resembling something that could be imagined as:

<html lang="[node:language]" >
<title>[node:title]</title>

(or some complicated theme-constructed permutation that was still essentially that)

The whole don't-break-existing-behavior thing certainly over-rules my expectations I guess!

There is no language selector when entering a translation,

Sorry, I thought we've been used to seeing one. I didn't realize that being able to choose the language when entering a translation was not a normal feature. I can't recall how many extra widgets we had to turn on to get the edit UI work the way was needed :-}
.. Ah I see what you mean. I *do* see a selector on the edit page, but it's then disabled on the translations pages. You choose the 'base' language and all the other versions still are somewhat pinned to that. And that's the thing you are saying we shouldn't really pretend to change. Hm. Somehow I'd figured that was the thing where you selected the language of the thing being edited. My memory must be tricking me. I don't do a large amount of the actual data-entry myself. Maybe I should spend more time actually using the UI instead of turning it on and handing it over ...

I *think* I've learnt a little more about the internals of translation again today. (I'm the only monolingual-dev in our mid-sized-team, yet *I* get lumbered with supporting this stuff *and* explaining it to clients ... :-} )

I'll see about cleaning up option B as a renamed patch then!

dman’s picture

Oh BLAST.

After my facetious HTML HEAD example, I checked and found that - although this token can be used in our metatags for dcterms.language ... The real HTML HEAD (html.tpl from Omega theme) that goes
<html lang="<?php print $language->language; ?>" dir="<?php print $language->dir; ?>"<?php print $rdf->version . $rdf->namespaces; ?>>
still is getting it wrong.

I now have the meta OK, but the HTML lang="en" still.

<html lang="en" dir="ltr">
<head>
<meta property="dcterms.language" content="mi" />
<meta property="dcterms.title" content="Me kai tahi te whānau ina taea ana" />
...

(Also the same in Garland and logged out)

I guess that has to be fixed in another place still... A different issue?

dman’s picture

Quick research points at D8 locale_preprocess_node().
Does this mean we should add an entity_translation_preprocess_page() to fix up the $variables['language'] ?

plach’s picture

Does this mean we should add an entity_translation_preprocess_page() to fix up the $variables['language'] ?

A page can have various nested level of markup each one with its own language. The root level uses the negotiated interface language, i.e. the language strings passing through t() are translated in. This language is independent from the translation language. If you configure language negotiation settings in the language detection and selection page to use the same method (e.g. URL) for both the interface and the content language, the HTML lang attribute should match the translation language, provided that the translation exists.

Edit: well, looking at the actual code it wasn't meant to work that way. I guess it has been changed without notifying me :(

Edit2: actually that is D8 code that has nothing to do with the <html> tag attributes. My answer above should be correct.

dman’s picture

Yeah, saw the issues in the queues about having different chunks of content with different languages. I'm down with that, though I know that it looks like it's got to be a D8 thing.

The root level uses the negotiated interface language

Ah. Oh boy.
And because we are *not* using interface translation at all (these are just fact sheets, we are not translating the IA) ... that will not trigger. And adding the entity language into the meta headers means I'm actually putting it in the wrong scope now.
Wow, this stuff is hard.
Now how do I explain this to the 'testers' that initially raised the complaints about the language tags? *sigh*

Thanks for your patience and help here!!

plach’s picture

If the solution above is not viable I can only suggest you to override the language attribute by using a html.tpl.php preprocessor function.

dman’s picture

Yeah, that was where I was going with the entity_translation_preprocess_page() idea.
But I accept that this would be more like a fringe tweak right now than anything I would propose here yet.

dman’s picture

Issue summary: View changes

detail

dman’s picture

Issue summary: View changes
FileSize
198.3 KB

I was asked about this one again today - SO I re-summarized it for a client again.
Just dropping this up here for reference:

howto tag mixed-language content

And an imagining of how this can be applied to Drupal7 fields:

/**
 * Add per-field language attribute.
 * 
 * This is relevant if using entity_translation when only part of a site or 
 * page is actually translated. The language is a property of the field being
 * displayed, not of the site or the page.
 * @see https://drupal.org/node/2033591
 */
function THEMENAME_preprocess_field(&$vars) {
  if (isset($vars['element']['#language']) && $vars['element']['#language'] != LANGUAGE_NONE) {
    foreach ($vars['items'] as $delta => $val) {
      $vars['item_attributes_array'][$delta]['lang'] = array($vars['element']['#language']);
    }
  }
}

Bohus Ulrych’s picture

Hi,
I was facing same issues - to get proper language code for dcterms.language
Patch #8 seems to be working, #9 after some modifications. But at the end I realized that simple token for the current language will be enough.
Would be possible to create new token with this value:

global $language;
print $language->language;

This will help a lot!
Thanks

DamienMcKenna’s picture

As the current maintainer of the Metatag module, if there's anything that could help make this easier from the Metatag side, let me know and I'll take a look.

Nchase’s picture

#8 works for me. #9 doesn't.
But with #8 the hreflang [node:url-LANGCODE] doesn't work anymore.