Jump to content

Search in multilanguage site with multilang fields


seddass
 Share

Recommended Posts

Hi all,

Hope that there is a quick tip that someone already know...

Is it possible to search in multilanguage fields only in the current language values without to search in the default language as fallback? See the quote below.

We will assume that the current user's language is Dutch and that this is a language installed in the system. We will also assume that the field "body" is a multi-language textarea field. Because the user's current language is Dutch, the following API call matches any pages that contain the phrase "welkom vrienden" (welcome friends) in the Dutch body field OR the default body field. If there are other languages installed, it does not attempt to search them.

In other words.. I would like to search only in the current language (Dutch), no matter if some of the Dutch language values are empty. Is it possible?

Thanks

  • Like 1
Link to comment
Share on other sites

Not technically a supported feature at present, but I think you can get the result you want. You'd take a query like this:

$pages->find("body*=something");

and convert it to this:

$pages->find("body.data{$user->language}*=something"); 

That should return just the pages that match the current user's language, rather than including the default language.

  • Like 4
Link to comment
Share on other sites

  • 5 months later...

Not technically a supported feature at present, but I think you can get the result you want. You'd take a query like this:

$pages->find("body*=something");

and convert it to this:

$pages->find("body.data{$user->language}*=something"); 

That should return just the pages that match the current user's language, rather than including the default language.

Sorry to dig this up, but I've followed these instructions, changing:

$matches = $pages->find("title|body|sidebar*=$q, limit=50, id!=1"); 

to

$matches = $pages->find("body.data{$user->language}*=$q, limit=50, id!=1"); 

and the following error shows up:

Error Exception: Unknown column 'field_body.data1029' in 'field list' (in /home/v3maran/public_html/wire/core/Database.php line 118)

Any clue why this is happening? I am using the built in multilanguage module. Thank you.

Link to comment
Share on other sites

(Edit: This just got deprecated ;), but I'll still leave it here - see "Part 2").

Go and see Setup -> Fields -> body. What's the type of the field?

I'm guessing it's "Textarea" as there doesn't seem to be fields for different languages in the database. That kind of selector would work only for fields of type *Language, "TextareaLanguage" in this case most likely.

You can change the type safely, but still after that for the selector to work in a reasonable way you'd have to input some content in the very language you're using in your search. But that was actually what you must have been trying to do anyway. :)

(..a few hours later..)

Part 2

Had another idea a bit later and while the earlier explanation could have been right, there's another possibility as well. And I think this is much more probable than the first one as I can't understand why you'd be using a selector like that if you didn't already have actual multilingual data in there - stupid me.

So now I'm thinking 1029 is the id of you default language (see Setup -> Languages -> default - what's the value of id parameter?). That special kind of selector would only work for languages other than the default one as its field is named just "data", not "data1029" for instance. So when the language is set to default ($user->language->name == 'default'), you'd have to use a regular selector without the ".data{$user->language}" part (or just ".data" without the id, I think).

Next part will follow in the morning - hope not.

Edited by nik
  • Like 2
Link to comment
Share on other sites

Nik is right about this. You probably want to change your selector to something like this:

$field = $user->language->isDefault() ? "body" : "body.data" . $user->language; 
$matches = $pages->find("$field*=$q"); 

That will force it to not consider the default language in the matches at all.

However, most of the time you should just do this, which already takes languages into account:

$matches = $pages->find("body*=$q"); 

So whether the user searches for "Beer" or "Cerveza" they will still get to the right page. If you exclude the default language, then that fallback never happens.

  • Like 5
Link to comment
Share on other sites

Thanks for both answers. My content fields are all multilanguage and work perfectly with everything else.

I implemented the changes Ryan pointed out and the error is gone. However, now the language resets always to the default one. I type the string, hit the button and the language changes back and displays results on that specific language.

You can check it here: http://maran.pt/

Try searching in portuguese (default) for "armario" and then, in english for "locker".

Link to comment
Share on other sites

I have that set in the header, it should load properly. However, I may have another loophole when I build the search form:

<form id='search_form' action='<?php echo $config->urls->root?>pesquisa/' method='get'>

The 'pesquisa' is the name of the search page. I believe this should change in order to get the /pt/ or /en/ after it, right?

Link to comment
Share on other sites

I think this will just depend on how and where you are setting the language. You'll want to make sure you are setting $user->language somewhere before your search (and before any output).

I now realized that part. Search.php treats things differently, so I would need to set the language before the output construction. However I am still unaware on how to achieve this since I tried to use the head.inc language related code lines, and nothing resulted from that. Here's what I have:

$lang = $user->language;
$langname = $lang->name == 'default' ? 'pt' : $lang->name;

I make no sense of this because I don't think it is setting anything (just storing the current languag in variables for further use), but everything else works. How can that be? I am confused now... ???

Link to comment
Share on other sites

When switching to language en, the search form is not changing it's action url.

<form id='search_form' action='/pesquisa/' method='get'>
 <input type='text' name='q' id='search_query' value='' />
 <button type='submit' id='search_submit'>Search</button>
</form>

When I manually enter http://maran.pt/en/search/?q=locker it seems to work.

  • Like 1
Link to comment
Share on other sites

Yes, Soma, I agree with you on that. I believe I have to place the language alias before. And about that, I have a question that is connected to this problem. When I want to link to a page, instead of typing the URL with the normal name, I would like to get the URL depending on the language I am at. Here's what I do, but I think this solution is not vert elegant...

$homepage = $pages->get("/");
$children = $homepage->children->find("name=pagename");
$child = $children->first();

Then I use $child->url for the url's link. Is there a easier way?

Link to comment
Share on other sites

  • 1 year later...

1.

$field = $user->language->isDefault() ? "body" : "body.data" . $user->language; 
$matches = $pages->find("$field*=$q"); 
2.
$matches = $pages->find("body*=$q");

WOW! The first one just made my day..thank you!!  :)

The second one is not working for name field is that correct?

Couldn't get it working $pages->get("name*=$q") it's only getting default language (find-> wasn't working for me neither)?

Link to comment
Share on other sites

  • 4 years later...
On 9/30/2012 at 6:00 PM, ryan said:

Nik is right about this. You probably want to change your selector to something like this:


$field = $user->language->isDefault() ? "body" : "body.data" . $user->language; 
$matches = $pages->find("$field*=$q"); 
 

That will force it to not consider the default language in the matches at all.

However, most of the time you should just do this, which already takes languages into account:


$matches = $pages->find("body*=$q"); 
 

So whether the user searches for "Beer" or "Cerveza" they will still get to the right page. If you exclude the default language, then that fallback never happens.

Hey,

I just wanted to say that this kind of functionality is super important for many websites. I just spend three hours looking for a solution until I stumbled on this. Seriously consider adding it to the documentation.

Now I can easily show only news item that actually has content in the relevant language.

  • Like 2
Link to comment
Share on other sites

  • 1 year later...

Maybe it is worth rethinking this implementation? When checking is a field is empty or not, for example, fallback to default is a bug. The hack solution is kinda ugly and unintuitive.
And one of PW's strongest points is multi-language support. What do you think,  @ryan?

P.S. I just tried it out one more time. It seems that if you check if the field is empty using just the field name, it checks only the default language. So if the field has text in user lang but not in default, the check is falsely false. So might be a real bug here.

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...