The options key 'language' is undocumented.

When backporting to 6, would need adding to http://api.drupal.org/api/function/hook_links too.

Comments

jhodgdon’s picture

Title: Documentation problem with l » documentation for l() missing language key

Good catch: options['language'] is indeed undocumented on http://api.drupal.org/api/function/l/7 as well as http://api.drupal.org/api/function/l/6 in Drupal 6.

I'm not sure what you are talking about with hook_links -- that doesn't exist?

Did you perhaps mean http://api.drupal.org/api/function/theme_links/7 ? If so, I think it should just say "Other array items are passed on" instead of "Array items are passed on", and not document all the array options in two places.

And the D6 version of theme_links should do the same thing.

trevjs’s picture

Assigned: Unassigned » trevjs
trevjs’s picture

Status: Active » Needs review
StatusFileSize
new2.12 KB

Added a description for language in the list of appropriate keys for option. I used the same exact wording from the url function. I also brought the entire list of keys up to document standards.

joachim’s picture

Ah, typo -- I meant http://api.drupal.org/api/function/hook_link. That exists only in 6 and prior, and takes options in the same format as l().

joachim’s picture

Patch looks good.

However, in my wander through the code I found an added subtlety of the language parameter: if you pass nothing, then the current language is assumed. This could do with a mention, as well as the correct way to pass the default language. This came up on image module (#540692: language prefix causes wrong path to image directory) and passing an empty string for language seems to work, but I don't know if it's the Right Thing. Some input from someone who's worked on or developed the language handling in core is needed.

jhodgdon’s picture

trevjs: Excellent work on that patch -- thanks for cleaning up the formatting.

Here's my take on things to add/fix, from the above comments and looking through the code:
- In both url() and l(), add a note saying to omit 'language' to use the current page's language.
- Make a note in both url() and l() that the language is used to look up the path alias (if any).

I'm filing a separate issue on l() about the use of the global $language_url, which as far as I can tell, is used but never set in core (WTF?).

joachim’s picture

Sounds good.

My comment #5 possibly wasn't clear -- how do you create a link that is language-neutral, for example to a file? This is the problem I've encountered with image module.

jhodgdon’s picture

Looking at the code, it looks like if you just leave out the 'language' component of options, you will have a language-neutral link.

joachim’s picture

My impression --as you say above in #6 is that if you pass in nothing you get the current page's language.

*sigh* This is why code documentation has to be written by the people who write the code!

jhodgdon’s picture

Hmmmm... What do you actually mean by a "language neutral link"?

As far as I can tell, the only things that the language option or current language affects are (a) whether the link is marked as "active", and (b) which URL alias is looked up. If that is even working (see #724504: global $language_url and similar globals need documentation)....

Ah, I see.... http://api.drupal.org/api/function/locale_url_outbound_alter/7, which will probably be calling http://api.drupal.org/api/function/locale_language_url_rewrite_url/7 to alter the URL...

It looks like for rewrite_url(), if $options['language'] is omitted, it won't alter the URL, given that it's using the global $language_url variable, which I think is never set (see issue 724504, link above).

joachim’s picture

TBH I am not entirely sure what I mean -- see #540692: language prefix causes wrong path to image directory.

I *think* I mean on a site where the language code prefixes the paths, like 'example.com/fr/node/64', you still want a link to a file to be 'example.com/sites/default/files/myfile.jpg' (without a language prefix).

jhodgdon’s picture

It looks like that outbound alter function http://api.drupal.org/api/function/locale_language_url_rewrite_url/7 will not alter a link if you leave off $options['language'], unless the global $language_url is set. Which again, I have no idea when/how/if that is ever set anywhere.

But... if the URL is altered, the site should still process it correctly? If not, that's the real bug on that other issue.

jhodgdon’s picture

Status: Needs review » Needs work

We all forgot the status change.

joachim’s picture

> But... if the URL is altered, the site should still process it correctly? If not, that's the real bug on that other issue.

If it's a URL to a public file, Drupal won't even see it.

jhodgdon’s picture

I see what you mean.

trevjs’s picture

So I think we are still figuring it out, but it sounds like it should be something like this:

+ *     - language: An optional language object. Used to build the URL to link
+ *       to and look up the proper alias for the link. If a language is not defined
+ *       in options then the function will check to see if the language is defined
+ *       in the url, otherwise it will default to the language of the site.

There is a probably an easier way to say this, and I don't think language is defined as a variable in the url, I think it might be part of the path. But I'm new here. I'll check back tommorow and see if we have a definate understanding of this.

joachim’s picture

"If a language is not defined in options" makes me think of a system-wide setting. Do you mean rather something like: "If no language is passed in..."?

jhodgdon’s picture

RE: #17 -- should probably say "If $options['language'] is not set".

But anyway, what it's doing if that is not set is ... hmmm...

It turns out that the global $language_url is the language that was defined by the URL of the current page (someone responded to my other issue). So if your site uses domains like de.example.com, or URL prefixes like example.com/de/, whatever the current page URL request was, that will define $language_url.

Why that and not the fully negotiated language for the page is being used in l(), url(), and theme_links() is a mystery to me.

Anyway, that aside, how about:

- language: An optional language object. If the path being linked to is internal to the site, $options['language'] is used to look up the alias for the URL, and to determine whether the link is "active", or pointing to the current page (the language as well as the path must match). If $options['language'] is omitted, the language defined by the current page's URL will be used; this depends on the site's language negotiation settings (sub-domain or URL prefix).

Or something like that... This would be for l(). For url(), the part about determining whether the link is active should be omitted. Can you fix both of them?

trevjs’s picture

Status: Needs work » Needs review
StatusFileSize
new3.45 KB

patch for l and url. If this passes then we will need to look at what needs to be done for Drupal 6.

Status: Needs review » Needs work

The last submitted patch, l-url-19.patch, failed testing.

jhodgdon’s picture

Status: Needs work » Needs review

#19: l-url-19.patch queued for re-testing.

jhodgdon’s picture

Status: Needs review » Needs work

Assuming that the test bot agrees, (doc-only patch, it should), I think this is VERY close.

I saw one place where there was a space at the end of the line:

+ *     negotiation settings (sub-domain or URL prefix). 

That needs to be removed.

And there is one small clarification. In the url() doc [top part of patch], the default is actually the negotiated language, not the languge defined by the URL:

+ *   - 'language': An optional language object. If the path being linked to is
+ *     internal to the site, $options['language'] is used to look up the alias
+ *     for the URL. If $options['language'] is omitted, the language defined by
+ *     the current page's URL will be used; this depends on the site's language
+ *     negotiation settings (sub-domain or URL prefix). 

The default part could be simply stated:

"If $options['language'] is omitted, the global $language will be used."

trevjs’s picture

Status: Needs work » Needs review
StatusFileSize
new3.33 KB

With the suggested changes.

joachim’s picture

Did anyone figure out the correct way to specify a link is language-neutral?

jhodgdon’s picture

Well, let's see.

In l(), $options['language'] is used to determine if the link should be given the "active" class. That is done if $options['language'] is empty or if it matches the global $language_url.

Then $options is passed on to url(), without adding to it.

In url(), i$options['language'] is only used to pass to drupal_get_path_alias, which passes language on to drupal_lookup_path.

In drupal_lookup_path(), if language is not specified, it uses the global $language_content. And it looks up path aliases that are either marked with the chosen language or as language neutral.

That's what these functions do. I have ZERO idea why some are using $language_url, some are using $language_content, and some are using $language. I also don't think I understand really what you mean by "specify that a link is language-neutral".

joachim’s picture

By a language-neutral I mean a link that should have NO language identified in the URL. So for instance, a node that is marked as language neutral is just /node/xx and not /en/node/xx. A link to a file should be language-neutral too.

jhodgdon’s picture

Hmmm...

It looks like the link altering is done via http://api.drupal.org/api/function/locale_url_outbound_alter/7
(hook_url_outbound_alter()), which is called from url() via drupal_alter()....

Hmmm...

That will call http://api.drupal.org/api/function/locale_language_url_rewrite_url/7 or a similar function, unless $options['external'] is TRUE, and it will use the global $language_url if $language is omitted.

So I am not seeing any way except setting 'external' => TRUE to bypass this.

That's probably a separate issue though... in fact, I think I saw one about this somewhere, but I don't recall right now where...

trevjs’s picture

I think I get what you are saying... If a person is on a page /en/foo and you want to specify a link that goes to page /bar that is in the default language of the site, how do you force it to switch out of /en.

What happens if you pass $options['language'] equals english, and this is the default language of the site? Does it take you to /en/bar or /bar?

jhodgdon’s picture

That would depend on the settings you have for languages on the site.

jhodgdon’s picture

Status: Needs review » Needs work

Anyway, all of that aside, I think the latest patch is fine, except it needs a blank line between the @param sections and @return.

See third example here:
http://drupal.org/node/1354#functions

Other than that, I would say let's get this patch in.

trevjs’s picture

StatusFileSize
new3.34 KB

The no space between the param and return sections seems to be a common problem throughout the file. Is this something to create an issue about?

Anyways here is my patch.

trevjs’s picture

Status: Needs work » Needs review
jhodgdon’s picture

Status: Needs review » Reviewed & tested by the community

Looks good, thanks trevjs!

Regarding creating a new issue for all the missing lines between @param and @return -- well. It's an issue in almost all of Drupal. If you feel like patching a particular file, you can make an issue with a patch for that file. Otherwise, we're just fixing them piecemeal. Sigh.

jhodgdon’s picture

And I think there are better ways to spend your time than putting blank lines before all the @returns in Drupal. :)

jhodgdon’s picture

Bump... Could we get this one in?

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

trevjs’s picture

Version: 7.x-dev » 6.x-dev
Status: Fixed » Needs work

Now that it is in 7 I believe I need to add it in for 6.

jhodgdon’s picture

Status: Needs work » Patch (to be ported)

Correct!

jhodgdon’s picture

Version: 6.x-dev » 7.x-dev
Status: Patch (to be ported) » Fixed

Actually, let's not port this patch. Instead, let's wait until #303987: l() documentation needs to say something about url encoding is fixed in D7 and then port that instead, because it's changing ulr() and l() doc again.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.