GetSimple Support Forum

Full Version: Support for multilanguage sites, Internationalization (I18N)
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
Hello,

first of all I'd like to thank mvlcek for his excellent plugins but I always missed one feature, the possibility for having a localized slug. So I tried to write it myself and here's my working solution.

It simply works with adding _yourLocalSlug at the end of your slug

An example for a "About" page in english (default), french and german

english slug = about
french slug = about_fr_a-propos (frontend page url = fr/a-propos)
german slug = about_de_ueber-uns (frontend page url = de/ueber-uns)

but you don't have to add the translated slug so it won't break your existing pages, you can still use
french slug = about_fr (frontend page url = fr/about)


For this to work you have to make the following changes in your php files

in plugins/i18n_base.php

insert before add_action('index-pretemplate', 'i18n_init');

PHP Code:
add_action('error-404''i18n_local_slug'); 

insert after the i18n_init() function

PHP Code:
function i18n_local_slug() {
  global 
$id;
  require_once(
GSPLUGINPATH.'i18n_base/frontend.class.php');
  
I18nFrontend::setLocalizedSlug($id);


in plugins/i18n_base/frontend.class.php

insert before the load($lang) function

PHP Code:
public static function setLocalizedSlug($id) {
      global 
$data_index;
    
    
$langcode substr(self::getLangURL(), -3, -1);
    
    
$file_array glob(GSDATAPAGESPATH '*' '_' $langcode '_' $id .'.xml');
    
    if(
file_exists($file_array[0])) {
        
$data_index getXml($file_array[0]);
    }
  } 

The code can normally be inserted everywhere in these files (maybe not the add_action, but not sure) but it seemed to me to be appropriate like this.

For the navigation

in plugins/i18n_navigation/frontend.class.php

in public static function getPages

add after
if (strpos($filename,'_') !== false) {
$pos = strpos($data->url,'_');
$url = substr($data->url,0,$pos);
$lang = substr($data->url,$pos+1);

the following
PHP Code:
if (strlen($lang) > 2) {
    
$pos strpos($lang,'_');
    
$slug substr($lang,$pos+1);
    
$lang substr($lang,0,$pos);
    } 

and after
if ($menu) self::$pages[$url]['menu_'.$lang] = stripslashes($menu);
if ($title) self::$pages[$url]['title_'.$lang] = stripslashes($title);

the following
PHP Code:
if (isset($slug)) self::$pages[$url]['slug_'.$lang] = $slug

in public static function getMenu
add after
$slug = '' . $slug;

the following
PHP Code:
$pos strpos($slug'_');
if(
$pos 0$slug substr($slug0$pos); 

in private static function getMenuImpl
add after
'title' => self::getProperty($childurl,'title',$deflang),
'link' => self::getProperty($childurl,'link',$deflang),

the following
PHP Code:
'slug' => self::getProperty($childurl,'slug',$deflang), 

in public static function getMenuHTMLImpl

replace
$href = @$item['link'] ? $item['link'] : (function_exists('find_i18n_url') ? find_i18n_url($item['url'],$item['parent']) : find_url($item['url'],$item['parent']));

with
PHP Code:
if (!isset($item['slug'])) {
$href = @$item['link'] ? $item['link'] : (function_exists('find_i18n_url') ? find_i18n_url($item['url'],$item['parent']) : find_url($item['url'],$item['parent']));
}
else {
$href = @$item['link'] ? $item['link'] : (function_exists('find_i18n_url') ? find_i18n_url($item['slug'],$item['parent']) : find_url($item['slug'],$item['parent']));


And for the administration

in plugins/i18n_base/pages.php

change
$lang = substr($data->url,$pos+1);
to
PHP Code:
$lang substr($data->url,$pos+1,2); 

add after (before the closing "}" )
if (isset($page['variants'][$lang])) {
$variant =& $page['variants'][$lang];
if ($variant['title'] == '') $variant['title'] = '[No Title] &nbsp;&raquo;&nbsp; <em>'. $variant['url'] .'</em>';

the following
PHP Code:
$localslug $variant['url'];
$localslugarray explode("_"$localslug);

if (isset(
$localslugarray[2])) {
    
$localslug $localslugarray[2];
    }
else {
    
$localslug $localslugarray[0];
    }
    
$file_array glob(GSDATAPAGESPATH $page['parent'] . '_' $lang '_' '*' .'.xml');
    
if(
file_exists($file_array[0])) {
$localslugparentarray explode("_"basename($file_array[0], ".xml"));

if (isset(
$localslugparentarray[2])) {
    
$localslugparent $localslugparentarray[2];
    }
else {
    
$localslugparent $page['parent'];
    } 

and replace
<a title="<?php echo i18n_r('VIEWPAGE_TITLE').': '.stripslashes($variant['title']); ?>" target="_blank" href="<?php echo find_i18n_url($page['url'],$page['parent'],$lang); ?>">#</a>

with
Code:
<a title="<?php echo i18n_r('VIEWPAGE_TITLE').': '.stripslashes($variant['title']); ?>" target="_blank" href="<?php echo find_i18n_url($localslug,$localslugparent,$lang); ?>">#</a>

That's it (if I didn't forget to write down some changes I made).

I tested it with a newly installed GetSimple 3.2.1 and I18N 3.2.2 and fixed every issue I encountered.

This can probably be made in a more elegant way and I hope mvlcek will add this to his plugin (and fix the compatibility issues that will probably come with the other I18N plugins)
I once knew how to do but I really forgot and can't find the solution in the moment, but there is a demand concerning this in the german sub-forum:

how to include a page first-level menu, which has children pages, but no content itself? So the item should not be a link, only to show the children pages?
Thanks in advance and forgive my bad memory ;=)
(2013-07-24, 18:05:47)Connie Wrote: [ -> ]I once knew how to do but I really forgot and can't find the solution in the moment, but there is a demand concerning this in the german sub-forum:

how to include a page first-level menu, which has children pages, but no content itself? So the item should not be a link, only to show the children pages?
Thanks in advance and forgive my bad memory ;=)

You need to use Custom Rendering.

Create a component e.g. navitem:
Code:
<li class="<?php echo $item->classes; ?>">
  <?php if ($item->hasChildren) { ?>
    <span class="nav"><?php echo htmlspecialchars($item->text); ?></span>
    <a href="<?php echo htmlspecialchars($item->link); ?>">
      <?php echo htmlspecialchars($item->text); ?>
    </a>
    <ul><?php $item->outputChildren(); ?></ul>
  <?php } else { ?>
  <?php } ?>
</li>
(this is just an example)

Call the navigation function like this:
Code:
<?php get_i18n_navigation(return_page_slug(),0,99,I18N_SHOW_MENU,'navitem'); ?>

And then you need some Javascript code to show/hide the submenu(s), when the user clicks on the <span>.
(2013-07-24, 19:13:52)mvlcek Wrote: [ -> ]Call the navigation function like this:
Code:
<?php get_i18n_navigation(return_page_slug(),0,99,I18N_SHOW_MENU,'navitem'); ?>

And then you need some Javascript code to show/hide the submenu(s), when the user clicks on the <span>.

So it is not a standard function where a click shows the children-pages but does not open a page..

thanks! So we have an answer to the question in the german forum!

I will check on my local server, maybe I still have that experiment, but I think I may have deleted it..

but now we know, danke!
Just for information.

My localized slug solution posted 2 days ago also allows the creation and use of translated pages without an existing default language page.

If I take my previous example for a "About" page in english (default), french and german

english slug = would be "about" but the page don't have to be created, but can be created later if needed
french slug = about_fr_about (frontend page url = fr/about) if you want the same slug for every language
german slug = about_de_ueber-uns (frontend page url = de/ueber-uns) if you want to use a localized slug

It also seems that there's a problem with the View Page link on the administration, parent isn't included for a translated page without localized slug and parent for a translated page without an existing default language page is not the right one.

The translated page without an existing default language page is also not displayed on the frontend navigation.

I'll try to fix that when I have some time.
Hello,
I have my first client who wants to have a 3rd level in their menu structure. I've added another page and using the "Edit Navigation Structure" moved it so it appeared under a second level item. For some reason the new item does not appear. As soon as I move it to the second level it appears OK.

The new "third Level" link does not appear in the page code but I can get to it manually by typing in the slug. I've made sure the "Add to page menu" is checked.

Is there something else I need to check or confirm. I thought it might be a CSS issue but the link doesn't even appear in the code.

Any ideas?

By the way the i18n plugin is ver 2.6 - I know it's old but does exactly what I want to do with it (until now that is Smile
(2013-07-26, 15:41:13)stryker Wrote: [ -> ]I have my first client who wants to have a 3rd level in their menu structure. I've added another page and using the "Edit Navigation Structure" moved it so it appeared under a second level item. For some reason the new item does not appear. As soon as I move it to the second level it appears OK.

The new "third Level" link does not appear in the page code but I can get to it manually by typing in the slug. I've made sure the "Add to page menu" is checked.

Make sure that the 3rd parameter (max level) to get_i18n_navigation is at least 2.
How can I remove ?lang=xx from canonical urls etc? I have only 1 language and
Code:
define('I18N_SINGLE_LANGUAGE',true);
doesn't work :/
Thank you
Thanks mvlcek - That's perfect. I'd hoped it would be an easy solution Smile
One of my clients by mistake created two additional languages by adding manually "_uz" to the slugs of some pages. Before they had two: RU and UZ.

After deleting those pages i've got two required language columns back, but I've just noticed, that there are "UZ" and "UZ" language columns, not "RU" and "UZ"..

When i try to set "RU" as a default lang for creating pages, the left column becomes "RU", however it turns back to "UZ" when I refresh the "pages" page.. ((

In the "General problems" forum I was told that this could be a cookie issue of il8n...
0zz if it's problem with cookies, use different browser or delete cookies, if not, edit page xml files that could cause the problem and it should be okay
Thank you! The had mistakes in "pages.xml" - there were pages which were not shown in the menu, besides I manually edited "i18n_settings.xml" file and everything got fine.

Thanks once again!
@mvlcek:

is is possible?

Quote:How can I remove ?lang=xx from canonical urls etc? I have only 1 language and
Code:
define('I18N_SINGLE_LANGUAGE',true);
doesn't work :/
Thank you
(2013-07-14, 17:19:00)mvlcek Wrote: [ -> ]
(2013-07-14, 08:30:48)bensayers Wrote: [ -> ]How can I make the external links open in a new window (_blank)? I've searched through the boards and documentation but I can't find the way it's done...

You would need to use Custom rendering and add the target to the <a>, when the link is external.

Can someone please help me with this issue? Seems like this should be a pretty common request - why wouldn't you want an external link to open in a new window?
(2013-08-09, 06:13:10)bensayers Wrote: [ -> ]
(2013-07-14, 17:19:00)mvlcek Wrote: [ -> ]
(2013-07-14, 08:30:48)bensayers Wrote: [ -> ]How can I make the external links open in a new window (_blank)? I've searched through the boards and documentation but I can't find the way it's done...

You would need to use Custom rendering and add the target to the <a>, when the link is external.

Can someone please help me with this issue? Seems like this should be a pretty common request - why wouldn't you want an external link to open in a new window?

Call
PHP Code:
<?php get_i18n_navigation(get_page_slug(false), 00I18N_SHOW_NORMAL'navigation'); ?>

Component (named 'navigation') - note: this was modified from mvlcek's example on his site
PHP Code:
<?php global $SITEURL?>
<li class="<?php echo $item->classes?>">
  <a href="<?php echo htmlspecialchars($item->link); ?><?php if (strpos($SITEURLhtmlspecialchars($item->link)) !== 0) echo 'target="_blank"';?>>
    <?php echo htmlspecialchars($item->text); ?>
  </a>
  <?php if ($item->isOpen) { ?>
    <ul><?php $item->outputChildren(); ?></ul>
  <?php ?>
</li> 

Key parts are:
PHP Code:
<?php global $SITEURL?>

(Gives site url for use in IF conditional)

PHP Code:
<?php if (strpos($SITEURLhtmlspecialchars($item->link)) !== 0) echo 'target="blank"'?>

(Says if the site url isn't found in the menu item's link, it's external, hence output 'target="_blank"').

Note: If get_page_slug(false) doesn't work, use return_page_slug() (I just used whichever one was in the latest GetSimple version, which at the time of speaking is 3.2.2).
Also there are jquery scripts to do this automatically.
(2013-08-09, 07:48:40)Angryboy Wrote: [ -> ](Says if the site url isn't found in the url, it's external, hence output 'target=blank').

You rock, thanks a ton, man! I'll give it a shot this weekend.
(2013-08-09, 08:01:48)shawn_a Wrote: [ -> ]Also there are jquery scripts to do this automatically.

Point taken. With this one from CSS tricks, you could use:

PHP Code:
<script>
$(
'#nav a').each(function() {
   var 
= new RegExp('/' window.location.host '/');
   if(!
a.test(this.href)) {
       $(
this).click(function(event) {
           
event.preventDefault();
           
event.stopPropagation();
           
window.open(this.href'_blank');
       });
   }
});
</script> 

If your navigational container's id is 'nav'.
(2013-06-19, 21:20:05)ohayo Wrote: [ -> ]Hi there.
I've go some strange issue with my site:
My homepage on Chrome is always displayed in english, but default lang should be polish. It works just fine in sub-pages and I can switch languages with no problem. On FF/IE/Opera homepage works normally.

I've tried changing the favicon path to root and even removing it completely but it doesn't work.
I'm using pretty urls:

%nondefaultlanguage%/%parent%/%slug%/

PHP Code:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond 
%{REQUEST_FILENAME} !-d
RewriteRule 
^(en)/(.*?/)?([A-Za-z0-9-]+)/?$ index.php?id=$3&lang=$[QSA,L]
RewriteRule ^(en)/?$ index.php?lang=$[QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond 
%{REQUEST_FILENAME} !-d
RewriteRule 
^(.*?/)?([A-Za-z0-9-]+)/?$ index.php?id=$2&lang=pl [QSA,L

and homepage template looks like this:

PHP Code:
<?php if(!defined('IN_GS')){ die('you cannot load this page directly.'); }
?><?php include('inc/doctype_'.$language.'.inc.php'); ?>

<title><?php get_site_name(); ?> / <?php get_custom_field('pagetitle'); ?></title>

<?php include('inc/fonts.inc.php'); ?>
<?php 
include('inc/styles.inc.php'); ?>
<?php 
include('inc/analytics.inc.php'); ?>
<?php 
include('inc/social_'.$language.'.inc.php'); ?>

</head>
<body>
<div id="container">
<?php include('inc/header.inc.php'); ?>
<!-- QUOTE -->
<div id="quote_holder">
    <div class="quote">
    <?php get_i18n_component('quote-1'); ?>
    </div>
</div>
<!-- QUOTE END-->
<!-- WRAPPER -->
<div id="wrapper">
    <div class="wrapperbg">
        <div class="wrapperact">
        <div class="title">
        <h5><?php get_i18n_component('main-haslo'); ?></h5><div class="myButton wycena"><?php get_i18n_component('wycena'); ?></div>
        </div>
        <br class="clear" />
        <div id="content">
            <div id="realizacje">
               <?php include('inc/mainfolio.inc.php'); ?>
            <div class="spacer2"></div>
            <?php get_i18n_component('main-qualities'); ?>
            </div>
        </div>
        </div>
    </div>
</div>
<!-- WRAPPER END -->
<?php include('inc/footer_first.inc.php'); ?>
<div id="tags">
<?php get_i18n_component('tags-1'); ?>
</div>
<?php include('inc/footer_second.inc.php'); ?>
</div>
<!-- CONTAINER END -->
</body>
</html> 

For anyone interested in resolving this problem on Chrome:
Just add
PHP Code:
define('I18N_IGNORE_USER_LANGUAGE',true); 
to the gsconfig.php file.

I don't know why auto language detection fails in Chrome and prevents user from changing lang on homepage. I've tested my site on two computers with different Win installed (Win7 PL, Win8 EN), Chrome set to Polish and couldn't force it to behave like other browsers.

Anyway this little change sorted out my problem and maybe will help mvlcek in pinpointing the problem.
Indeed, something is wrong with Chrome.
asked developers of Chrome.
I was reading something about it related to Paul Irish I think. It's chrome "feature"
BUG: duplicate language cookie entries (one for /, another for /example/, third for /smth/smth/) which are causing "random" language switching through the entire site.

Reason: cookies has scope based on url (directory) which were set.
// hints from http://stackoverflow.com/questions/76735...te-cookies

To fix it, change i18n_base/frontend.class.php:39 to this:
PHP Code:
setcookie(I18N_LANGUAGE_COOKIE$_GET[I18N_SET_LANGUAGE_PARAM], 0'/'); 
I had a similar problem today in Firefox. Depending on cookie settings I also got one cookie per page instead of a sitewide setting, so I had to set the language on each page altough I was using the official "setlang" method.
I'll give the fix a try.

Cheers,

Tom
I have another question:
The whole day I try to get the i18n menu to generate the correct classes for the isCurrent and isCurrentPath variables without success.
I initially tried a simple menu without custom rendering, but I didn't get the classes I need to make the current page/path stand out in the menu.
Now I tried with custom rendering, but the variables never become true, although I'm on the page.

Component "mainmenu":

<?php
echo '<li class="'.$item->classes;
if ($item->isCurrent) {echo ' current';}
if ($item->isCurrentPath) {echo ' path';}
....
?>

Everything else seems to work fine, but the only class I ever get is the page slug...

I call the menu like this:

<?php get_i18n_navigation('index', 0, 0, I18N_OUTPUT_MENU | I18N_FILTER_MENU, 'mainmenu') ?>

It's basically a static menu with just the toplevel pages.
I read through the docs ten times now but somehow I don't get any classes although it seems this should be trivial.

Thanks for any hint!

Cheers,

Tom
(2013-08-20, 07:03:26)enzy Wrote: [ -> ]BUG: duplicate language cookie entries (one for /, another for /example/, third for /smth/smth/) which are causing "random" language switching through the entire site.

Reason: cookies has scope based on url (directory) which were set.
// hints from http://stackoverflow.com/questions/76735...te-cookies

To fix it, change i18n_base/frontend.class.php:39 to this:
PHP Code:
setcookie(I18N_LANGUAGE_COOKIE$_GET[I18N_SET_LANGUAGE_PARAM], 0'/'); 

Doesn't seem to work for me. With fancy url's on Chrome won't allow me to change homepage language - it always english. Subpages work ok, but when I go back from polish subpage to homepage it switches back to english.

Now when I turn off fancy url's I can set polish language. Then Chrome remembers the cookie and it is possible to turn on fancy urls and everything is working fine. Until I clear the cookies Smile
Pages: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43