Jump to content
seddass

Search in multilanguage site with multilang fields

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

Share this post


Link to post
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 3

Share this post


Link to post
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.

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.

Share this post


Link to post
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

Share this post


Link to post
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

Share this post


Link to post
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".

Share this post


Link to post
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).

Share this post


Link to post
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?

Share this post


Link to post
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... ???

Share this post


Link to post
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

Share this post


Link to post
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?

Share this post


Link to post
Share on other sites

Well what multilanguage setup are you using there? Any modules?

Well the language switch links are already right. How are you generating the url on them or also on the navigation?

Share this post


Link to post
Share on other sites

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)?

Share this post


Link to post
Share on other sites
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 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Peter Troeger
      Hello 🙂
      I have set up pagination on a mulitlanguage site.
      I've done this before, but this time I have a problem I can't solve.
      Pagination is activated on 'parent-template' and 'child-template' just to be sure 🙂
      This is my code:
      $children = $page->children('limit=1'); foreach($children as $child) { $title = $child->title; echo $title; } echo $children->renderPager(); The navigation is output correctly and the link look correct as well 'parent-page/page2/'.
      But when I click the link, the site seems to redirect back to 'parent-page/
      Any help would be greatly appreciated 🙂
      - Peter
    • By Lmwt
      Hi forum,
      I have this list of fields with labels and I want to skip the displaying of labels for fields left empty (e.g. if field "logo" is not filled with an image, but it could also be text fields). Using count() and "continue" will always output either nothing or all labels.
      Is there a way to use the "skipLabel" method in the loop?
      foreach ($page->template->fields as $field) { if(!count($page->$field->logo)) {continue;} else { $etikette = $field->getLabel(); //get label in the current user language $content .= " <br><li class='pub-field'>$etikette<br> </li>"; //display labels as li $content .= $page->get($field->name) . "<br>"; // display values as li } } Thanks for your help!
    • By Jens Martsch - dotnetic
      Hi guys I need an estimate for the following task:
      I developed a job candidate application in ProcessWire and need an extension to a Lister Pro Page.
      My customer wants to display a summary table of the filtered data like in the attached screenshot.
      When you filtered the view, that summary should show how many candidates have which status according to the actual filtered view.
      If you change the filter, the summary table has to be updated also.
      Who can accomplish this task and what would it cost?
      I first need an estimate to tell it to my customer. If he says the price is ok I will provide you with FTP Data to a dev server version of  that tool.
      Thank you in advance.

    • By Lmwt
      Hello,
      and one more beginner question: I am using the multi-language site profile and having troubles targeting the region I want to populate in my templates due to delayed output. The list is now appearing on top of the nav bar 🙂 and the values of the fields on one line down the title. I want these fields to be displayed in a list underneath the title of the page, and I also would like the name of the field to be displayed as a string in front of the value... I dont know how to do this. Can someone help?
      right now my code looks like this: 
      <?php namespace ProcessWire;?> <!DOCTYPE html> <html> <li class="Pub-profile-info"><?php $content .=page()->Location?></li> <li class="Pub-profile-info"><?php $content .=page()->Pub_country?></li> <li class="Pub-profile-info"><?php $content .=page()->Since?></li> <li class="Pub-profile-info"><?php $content .=page()->Contact?></li> <li class="Pub-profile-info"><?php $content .=page()->Focus?></li> <li class="Pub-profile-info"><?php $content .=page()->Members?></li> <li class="Pub-profile-info"><?php $content .=page()->Location?></li> <li class="Pub-profile-info"><?php $content .=page()->Decision_making?></li> <li class="Pub-profile-info"><?php $content .=page()->Financing?></li> <li class="Pub-profile-info"><?php $content .=page()->History?></li> <li class="Pub-profile-info"><?php $content .=page()->images?></li> <li class="Pub-profile-info"><?php $content .=page()->logo?></li> </html> and the screen looks like that:
      Thanks for helping!

    • By LuisM
      Hi there,
      im a bit lost right now. I added an hook after templates::save which should get the affected template and write its template ID into a JSON.
      The problem is, the event->object gives me an instance of the templates class. How can I narrow this down to the saved Template and get its ID and fieldgroup?
×
×
  • Create New...