Hello,

SCENARIO
Synchronizing a development site to a production site (and sometimes vice-versa) we copy the database from the one site to the other (say development to production). The language domains are set using the i18n module's domain option (ie. not language prefix).

Lets say the languages are setup as follows using i18n:

PRODUCTION site - multilingual configuration:
Default language: English - en
Default language domain: www.example.com

Additional language: Spanish - es
Additional language domain: es.example.com

DEVELOPMENT site - multilingual configuration:
Default language: English - en
Default language domain: dev.example.com

Additional language: Spanish - es
Additional language domain: es.dev.example.com

PROBLEM
When we move the development database to the live site it still has the multilinguage domains settings for the development site. This means that when we go to the live site www.example.com any link on the page will be pointing to dev.example.com/...

THEORETICAL SOLUTION
It may be possible to set the language domain in the settings file and thereby override the database settings.

I've see the post about $conf['i18n_variables'] = array(... in the settings.php file but I have not found a way to set the i18n domain settings using the settings.php file. I've read many posts and search the issue queues but have not found a solution using the settings.php file. Maybe some one knows.

All the best,
Guy Saban

Comments

EricLondon’s picture

I've encountered the same problem. When I deployed my code from production to a development environment, I kept getting redirected to production. I added the following code to fix the issue, but I'm trying to find the best place to put it..

<?php
$language_default = variable_get('language_default','');
if ($language_default->domain != 'http://' . $_SERVER['HTTP_HOST']) {
  $language_default->domain = 'http://' . $_SERVER['HTTP_HOST'];
  variable_set('language_default', $language_default);
}
?>
guysaban’s picture

I have not tried but I am guessing you can do the variable_get and variable_set in the settings file.
With Drush installed you probably could use the Drush instructions for vset and vget.

colan’s picture

You can't do variable overrides in settings.php or with Drush. This is because these domain settings are put in the "languages" table; they are not Drupal variables. You could stick the above code in settings.php, but it's a bit of a hack. What really needs to happen is have core support these settings as variables that can be overridden.

Until that happens, I'd recommend adding Drush commands such as these to your deployment processes.

drush @site-alias sqlq "UPDATE languages SET domain = 'fr-language-domain' WHERE language = 'fr'"
drush @site-alias sqlq "UPDATE languages SET domain = 'en-language-domain' WHERE language = 'en'"
drush @site-alias cc 'all'

...after you move your DB to whichever site (dev, staging, etc.).

  • "site-alias" is the Drush alias for the site you've just deployed to.
  • "XX-language-domain" is the actual domain setting.
  • And the two-letter language code is the language that you're setting.
colan’s picture

Project: Internationalization » Drupal core
Version: master » 8.x-dev
Component: Code » locale.module
Category: support » feature

This is all in core now. Adjusting issue settings as appropriate.

colan’s picture

Title: Set language domain in settings.php » Allow language domain to be overridden in settings.php
Cyberwolf’s picture

Subscribing.

Damien Tournoud’s picture

Status: Active » Postponed (maintainer needs more info)

The site alias feature (the sites/sites.php file) is precisely designed for this type of things. Could someone check if it can be used this way?

kemo1’s picture

Subscribing.

mlncn’s picture

Issue tags: +SettingsAPI

Subscribing (and tagging as potential edge case for a possible SettingsAPI).

hkovacs’s picture

Issue tags: +i18n, +languages, +Drush4, +language domain

Another solution for Guys scenario:

Tested on:
Drupal 6.2
Drush 4

When running drush sql-sync, I used the --skip-tables-key provided to exclude tables from being tranferred. This leaves the dev languages table variables as their original desired values.

Example Source: example.drushrc.php

$options['skip-tables'] = array(
'common' => array('cache', 'cache_filter', 'cache_menu', 'cache_page', 'history', 'languages', 'sessions', 'watchdog'),
);

Script:

drush sql-sync @live @dev --skip-tables-key=common
plach’s picture

Component: locale.module » language system

subscribe

colan’s picture

@howiek03: I'd recommend being careful with that approach. If you upgrade Drupal on @dev, and the schema changes for the "languages" table, this change won't get propogated to @live because the table is skipped. Even if you run updatedb, the schema version pointer in the @live DB will say it's up-to-date, when that table isn't.

I'm actually using this approach to not overwrite Webform tables on @live, but this a contrib module, where each of them maintains its own schema version pointer. You can then update the code, run updatedb and then do the sql-sync. This won't work for core though, as it's already partially updated, so I'd avoid it.

hkovacs’s picture

@colan, I considered that when deciding which method to use (updates vs skip). I still opted for skip. At some point I might pay the price, but I am aware ahead of time.

bserem’s picture

After reading the above I decided to go with Colan (#3) and turn his commands to a bash-function.

The code:

#!/bin/bash
function fix-lang (){
if [ $1 ]
then
  if [ $1 = "live" ]
  then
    drush @$1 sqlq "UPDATE drp_languages SET domain = 'http://en.example.com' WHERE language = 'en'"
    echo "ENGLISH FIXED"
    drush @$1 sqlq "UPDATE drp_languages SET domain = 'http://el.example.com' WHERE language = 'el'"
    echo "GREEK FIXED"
    drush @$1 cc 'all'
    echo "ALL DONE"
  elif [ $1 != "live" ]
  then
      drush @$1 sqlq "UPDATE drp_languages SET domain = 'http://en.$1.example.com' WHERE language = 'en'"
      echo "ENGLISH FIXED"
      drush @$1 sqlq "UPDATE drp_languages SET domain = 'http://el.$1.example.com' WHERE language = 'el'"
      echo "GREEK FIXED"
      drush @$1 cc 'all'
      echo "ALL DONE"
  fi
else
  echo "No site specified"
fi
}

Drush aliases and subdomains should be the same in order for the above to work. For example @stage should be stage.example.com and @staging should be staging.example.com and @live should be the live site (example.com)!
As you can see the urls are hardcoded inside the function. I don't find this a problem because I have a different cpanel account for every site so I can change this function for each of my clients.

I suppose urls could be set as parameters, it might be good but it I believe could become tedius to write the url every time.

I hope somebody will enjoy the above code!

idflood’s picture

subscribing

colan’s picture

Status: Postponed (maintainer needs more info) » Active

The site alias feature (the sites/sites.php file) is precisely designed for this type of things. Could someone check if it can be used this way?

I just looked into it. It cannot be used this way. It can only be used for mapping site aliases to site directories. See example.sites.php for details.

betz’s picture

Can someone tell what the status is for Drupal 8?
Can a language domainname be overridden from settings.php?

plach’s picture

Status: Active » Fixed

It can be overridden through config overrides.

betz’s picture

Party!

Currently it's a pain each time manually editing my db with a local import.
Good te hear this is gone.

Status: Fixed » Closed (fixed)

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

Pere Orga’s picture

Version: 8.x-dev » 7.x-dev
Status: Closed (fixed) » Active

If this works for Drupal 8 but not for 7, could that feature be backported?

Iztok’s picture

There is a module for this for D7: https://drupal.org/project/language_domains

Pere Orga’s picture

Version: 7.x-dev » 8.x-dev
Status: Active » Fixed

That module looks very cool

Status: Fixed » Closed (fixed)

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

leymannx’s picture

To add an example snippet of what you need to put in your settings.php or settings.local.php:

$config['language.negotiation']['url']['domains']['en'] = 'my-en-url.localhost';
$config['language.negotiation']['url']['domains']['de'] = 'my-de-url.localhost';
$config['language.negotiation']['url']['domains']['es'] = 'my-es-url.localhost';
$config['language.negotiation']['url']['domains']['fr'] = 'my-fr-url.localhost';