For having different variable values per domain there's now a new API that is already used by Internationalization module to have different variables per language.

That API includes a variable_realm module which handles its own storage and aims to be an arbitrator for different modules using different variables for different realms (Realm = language, domain, etc...)

So if this makes sense and there's some interest I could start working on the patch to make this happen.

The full implementation for multilingual variables can be seen here, http://drupalcode.org/project/i18n.git/blob/refs/heads/7.x-1.x:/i18n_var...

Some usage examples of this API (taken from i18n_variable module):

  // To load and set variables for this language.
  $variables = variable_store('language', $language->language);
  variable_realm_switch('language', $language->language, $variables);

The advantage of this is that, besides some full API to store/retrieve variables for specific languages or domains, two modules could use it without conflicts. As 'realms' may have different weights, realms with higher weights override realms with lower ones, providing a full fallback system. It would look like this:

  // Load the variables for this domain.
  $variables = variable_store('domain', $domain_name);
  // Set a higher weight for domain realm so values override language variables
  variable_realm_switch('domain', $domain_name, $variables, 100);
CommentFileSizeAuthor
#22 domain_conf_variable_realm.patch14.27 KBJose Reyero
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Jose Reyero’s picture

agentrickard’s picture

Interesting. We're getting very close to a stable 3.x.0 release, so don't want to introduce this change now, but would be happy to look at folding it in in a later release.

I think my questions are:

  1. How can we leverage this new API to allow for per-language per-domain settings. In other words, can a realm be smart enough to know:
    • Var A on Site A in English
    • Var A on Site A in Spanish
    • Var B on Site A in English
    • Var B on Site B in English
  2. How early in the bootstrap process is this available? Right now, we load some domain-specific variables that run before caching, for instance.
gmclelland’s picture

I might be far out in saying this, but this sort of sounds like the http://drupal.org/project/spaces Module. Spaces gives you override-able variables, themes, contexts, boxes per space with the ability to bundle these configurations into presets. Perhaps it might be worth looking into creating a domain as a space type? There is already a space type for users, taxonomy, and organic groups.

You can see more about spaces here http://elearning.psu.edu/elearning/elms-botany-looks-why-spaces-so-powerful

The elms distribution uses this. http://drupal.org/project/elms

-Just a thought-
Of course this would be a huge change for DA

agentrickard’s picture

Domain Access predates Spaces by 3 years, so no.

I also despise PURL.

There is a Context Domain module, however, for folks who like that framework. http://drupal.org/project/context_domaint.

Mohammed J. Razem’s picture

This is a must!

Using multilingual sites with Domain requires having multilingual site name or slogan. And this should be integrated with Variable module.

agentrickard’s picture

@Mohammed

If it's a *must*, then you write it. I'm not made of time.

Posts like that just make me angry.

agentrickard’s picture

I will also point out that I had a patch to support this behavior about 2 years ago and no one ever reviewed it, so pardon me if I don't rush to support features I don't use.

Mohammed J. Razem’s picture

Hah! Don't get angry man, yeah it's a must and I'll work on patching this, when I have the time.

agentrickard’s picture

Just one of those weeks. I've got two clients who need 7.x.3 but not multilingual support. There are more pressing issues in the queue:

http://drupal.org/project/issues/domain?text=&status=8&priorities=All&ca...

This one, in particular, is important to i18n users: #1313610: Display proper messages for domain-specific settings.

agentrickard’s picture

Priority: Normal » Major

I just took a look at usage stats for i18n and Variable modules, and I think we should pursue this change.

Is anyone actually working on it?

lolandese’s picture

Played around with the variable api but my knowledge is too limited to write an initial patch. Following with interest and ready to review any upcoming patches.
Thanks for a great module successfully deployed on a shared host to circumvent the limit based on the number of DB tables.

agentrickard’s picture

I looked at the code and still have a number of problems with this approach, which I see as blocking implementation.

  • i18n, the module that uses this the most, form_alters itself into specific forms. Better that this was handled by the Variable API module itself, so that realm sensitivity could be set. We would have to do something similar, and would find ourselves in yet another race condition with i18n variables.
  • It's not immediately clear how the 'realm' context would work in our case. For domain-only variables, that's easy, but the use-case we're trying to solve is "this variable is domain and language sensitive." We might be better off simply adding a language column to the {domain_conf} table, which was my initial approach in d6.
  • The variable API acts too late. We actually act when variables are first loaded, which allows for things like caching per domain and maintenance mode per domain. We would have to work around this problem.
Jose Reyero’s picture

@agentricard,

- Right, variable realms don't provide an UI, though maybe something could be worked out if we have two modules implementing it. Anyway, handling site variables and language variables in the same form may be overkill. I doesn't do any assumption about storage either, though there's the variable store module as an optional API. Anyway, it provides all the widgets for you to build your 'domain variables form' anywhere.

- Realms are layered and have a weight so realms with higher weight override the ones with lower weight. This is where it may solve conflicts between modules trying to override the same variables. It also keeps track of where each variable belongs to so you don't need to worry about it and can switch back and forth. This is an example of how it could work:

1. Global realm, which are default variables
2. Domain realm, variables per domain.
3. Language variables which would be on top of domain variables, since a domain may have multiple languages.

Domain module would set its variables, then i18n. It doesn't matter which module does it first because which variable overrides which would depend on 'realm weights'. Weights can be configurable also.

// This would preset realms and variables but doesn't change any variable yet.
variable_realm_add('domain', 'example.com', $domain_variables, 10);
variable_realm_add('language', $language->language, $language_variables, 20);
// Now you can actually switch variables
variable_realm_switch('domain', 'example.com');
variable_realm_switch('language', $language->language);

Then at any moment you can switch back and forth between realms. I.e. if you want another language within the same domain.

variable_realm_switch('language', 'de');
// Run operations with german variables, then switch back to English
// Domain variables will be kept, though overriden by language variables (realm has higher weight);
variable_realm_switch('language', 'en');

Or you can also get/set any variable from any realm with a simple API, either for a page request or to be stored using variable_store.

// This would get the global variable (default, before domain and language overrides)
variable_realm_global_get($name);
// Or you can get the current value for the domain
variable_realm_get('domain', 'domain.com');

It could also handle other 'realms' like 'sections' or 'groups' which, depending on weight, would override or not the other variables.

- The variable API doesn't really switch variables, it is each module that sets its own set of variables. For instance, i18n uses hook_language_init() for that. Domain could run before, setting its own variables.

So though it doesn't fix all the problem, I think it would help a lot simplifying your variable handling and making it compatible with other modules (i18n for now) I'm going to take a look at the code and see how a patch would look like.

agentrickard’s picture

From reading the docs in the API, my understanding of how domain-language realms would interact is similar to the Spanish > Spain logic. e.g.

* Load default site variables.
* Load default domain realm variables. (These replace site vars, if set)
* Load language overrides for that domain. (These replace domain vars, if set)

In this scenario, the language-specific variables become nested as $variable[DOMAIN][LANGUAGE].

As I understand the feature request, this is the behavior people are after, and it isn't clear the realm weights allow for that style of nesting. So perhaps the solution is a flow like this?

* Domain realm weight is lowest.
* Domain loads its variables.
* Domain then loads i18n variables as a subset, if necessary.

From a UI perspective, helping people manage that configuration is a big challenge.

Jose Reyero’s picture

Realm weights don't really allow nesting they just set the order to override variables from different realms.

I can see two scenarios here, the first will be easier to implement:

1. Simple domain and language realms.

Depending on whether you want multiple languages per domain (a) or multiple domains per language (b), weights can be set in the right order. In this scenario variables would be either per domain or per language but not both. This has some limitations but would be way easier to handle. It doesn't need a very complex UI, current one will do.

1a. Multiple languages per domain. Load domain variables, load language variables on top.
1b. Multiple domains per language. Load language variables, load domain variables on top.

2. Complex mixed domain/language realms.

This would need more complex realms with domain x language. A domain key would be like 'domain1:language1'.
The most complex part of this would be the UI as we need to be able to set any combination of domain x language variables.

The loading order would be like:
- Current domain variables
- Current language variables
- Current domain x language variables.

The first case would be easy as we just need to use 'variable_realm' module for domain variables. The realm module will take care of overrides, etc.. The only thing we need to figure out is how to decide whether a variable is set per language or per domain.

The second case would be harder as we'd need to work some specific UI, maybe the domain module implementing multilingual variables on top of domain variables.

Some other feature we'd get and I forgot to mention is being able to build variable forms on the fly just from a list of variable names, that is built in into the variable module. I mean the domain_conf module wouldn't need to provide settings forms, domain variables could be selected as multilingual variables currently are.

agentrickard’s picture

I think #2 is what people are after.

Martijn Houtman’s picture

Yeah, #2 is the scenario I think we're looking for.

But why does this need to have a different UI than what i18n currently gives? I.e., a variable can be set to be a multilingual variable (and show the text 'This is a multilingual variable' below at the description), and will be saved for the language you are currently using the admin pages in. This will at least work fine for language-prefixed language selection, right?

agentrickard’s picture

It should. But if you need custom language settings per domain, it fails.

To see the problem enable i18n Variables and Domain Settings.

lolandese’s picture

#1 is sufficient for my use case.

agentrickard’s picture

@lolandese -- What prevents you from doing that now?

lolandese’s picture

An example is the site slogan. On example site A you see 3 languages. The slogan is set through admin/config/system/site-information for 2 languages (Dutch and English). The German (Deutch) slogan we didn't translate for demonstration purpose. Example site B is running under the same database. A different slogan is set for each language at [language-code]/admin/structure/domain/view/3/config. You can see that on the Dutch and English version of site B the slogan from site A appears, but not for the untranslated German slogan. Actually now the German slogan from site B appears on the German site A.
It might be me that's overlooking some settings elsewhere. Thanks.

Jose Reyero’s picture

Status: Active » Needs review
FileSize
14.27 KB

This is a first patch that replaces storage (by variable_store) and handling of global settings (by variable_realm). As you can see the module is really simplified and it will play nice with any other module using variable realms.

There's a lot of room for further simplification, like the whole administrative UI that could be reduced to a few lines of code, though this would be the first step. Not included update scripts.

Btw it needs latest (dev) variable module, which also includes features export for variable realms.

mstrelan’s picture

I don't want to hijack this thread, but I'm wondering if by integrating domain access with variable api the following scenario will be possible.

- I have a DA site
- I have a block from a custom module with custom fields
- The fields are currently saved using variable_set()
- I want to change the value of the fields per domain

lolandese’s picture

Trying the patch (domain_conf 7.x-3.3+8-dev) with the latest variable module (7.x-1.1+19-dev). The scenario is multiple languages per domain. We limit it to the slogan for now, set at admin/config/regional/i18n/variable.

Steps followed:

  1. On the default domain (ID 1).
  2. At admin/config/system/site-information it says at the top THERE ARE MULTILINGUAL VARIABLES IN THIS FORM. The slogan field is indicated as multilingual variable. A language can be selected.
  3. Also the top it says: You may submit changes to the current domain at admin/structure/domain/view/1/config.. Going there it says: This is your default domain. Use of this form is discouraged. Set these values through the standard interface. No messages about multilingual variables on this form. No language can be selected.
  4. Going back to admin/config/system/site-information we set a slogan for the default language. Save.
  5. We select another language from the top of the form and fill in the translated slogan. Save.
  6. A message at the top says: The configuration options have been saved for [site-name]. These settings will be inherited unless overridden per domain. The actual slogan field turned back to display the default language slogan. No translated slogan appears in the other languages.
  1. On the other domain (ID 2).
  2. Everything is identical as descibed above.

Once the slogan is set the only place to effectively alter it is admin/structure/domain/view/[domain-ID]/config.

We end up having different slogans on each domain but they result not translatable yet. This is already a small improvement because before we had to hard-code a different slogan into the theme although that one is translatable using the t() function.

Additional questions regarding #22:

.. the whole administrative UI that could be reduced to a few lines of code..

Couldn't find a UI to set realm weights. Is there a path it could be found or should it be hardcoded?

Not included update scripts

Should a manual update be performed?

Thanks.

Jose Reyero’s picture

This patch is just the first step, replacing realm module variable handling with variable module but it doesn't add any feature yet.

agentrickard’s picture

I'm wondering if it might be cleaner to write a new module from scratch -- Domain Variable -- rather than try to patch/change old behaviors.

I know Jose has put in work on the Domain Conf conversion, but I'd get a better feel for the Variable API starting over.

Jose Reyero’s picture

@agentrickard,

Well, I can try. However I am not sure how it will work having two competing sub-modules for domain variables, I mean, would they be both included with the main module? Will they both be separated modules? Because otherwise I don't see users replacing the domain_conf module coming with the default Domain Access.

agentrickard’s picture

That's for me to worry about, I suppose.

Domain Conf has been around so long (since d5) that I'd hate to mess with it for what is, in fact, a minor use case. I would think we'd get faster development splitting off a new module and providing an upgrade path away from Domain Conf for users who need it.

Domain Conf could provide a check for Locale or i18n and encourage users to switch to the other module.

But if you're putting in the work, I can see continuing on Domain Conf. If I were writing the code, I'd start a new module.

Jose Reyero’s picture

Well, yes, and no.

My interest for working on this is to get greater compatibility of other modules with i18n and to simplify maintenance overall, while also pushing adoption of Variable module (which would get more modules declaring their variables thus better compatibility with i18n system too).

But if we end up having two modules instead of one, maintenance will get still worse (We'll get issues from both sides) and also since domain_conf is the default module, I don't see this pushing too much addoption of Variable. That means (for me) more work in the long term, very little gain.

So as a module maintainer I really understand your point (keeping current sites working is way more important than cool new features). And I could work on a new module if the plan is it will eventually (once its fully working and tested) replace variable_conf and current system. But if the long term perspective is having two modules instead of one, please understand my interest on this is not that big.

This doesn't mean I don't want to work on this, only that it will have to wait till I get some client/project with this specific need (which I don't have atm, since I am using domain access for some sites but not together with i18n yet).

Still, building a new module from scratch instead of patching the old one may be the best solution but as I say it only makes sense (at least for me but also if you look at overall contrib maintainability) if the new one is to replace the old one at some point.

agentrickard’s picture

I think our goal should be to replace Domain Conf and Domain Settings with Domain Variable, while keeping the former two modules stable until the new one is finished. It might even require a 7.x.4 release and upgrade path.

I also wonder, long term, how CMI and D8 will affect things, so I'd like to isolate all that variable-loading code in a single place for easier upgrades.

I, too, would love for a project to come along where I need this feature, so I can work on it.

I'm just glad that you've pitched in with some practical advice and taken a shot at the code -- it gives us something to build on. What I think we really need here is a dedicated developer who needs to solve this problem.

Jose Reyero’s picture

Status: Needs review » Needs work

Ok, that sounds good.

So here's our new module (you're already project maintainer)

http://drupal.org/sandbox/reyero/1509768

(I've just updated file and funcion names)

Help wanted to work on that.

agentrickard’s picture

Perfect. I'm, going to clone and push a 7.x-1.x branch for further development.

agentrickard’s picture

Status: Needs work » Postponed

Issues should be filed here: https://drupal.org/project/issues/1509768

RobertoGuzman’s picture

bforchhammer’s picture

Is anyone working on this at the moment?

I have a project which I think would benefit greatly from this, and I'd like to have a go at moving this along...

agentrickard’s picture

There's a sandbox project for it. I'll give you access. https://drupal.org/sandbox/reyero/1509768

I am not actively working it.

bforchhammer’s picture

Thanks, agentrickard.

bforchhammer’s picture

Status: Fixed » Postponed

Status update for people following this issue:

The sandbox has now graduated to a full module: Domain Variable.

  • The module allows the specification of domain specific variables, for which values can be adjusted depending on the domain. This essentially replaces functionality from domain_conf, domain_settings, domain_theme...
  • It integrates with the i18n module to allow multilingual domain variables

There have been a lot of changes to the variable module to support these changes. As such, domain variable currently depends on the latest versions of related modules: variable-7.x-2.x (new branch!), i18n-7.x-1.x and domain-7.x-3.x!

There's still a few bugs and unfinished bits but overall it's becoming very usable in my opinion, and I would love to see some people testing it... If there are any issues using it, please create a new issue in the domain variable issue queue.

@agentrickard: is your goal still to include this in the domain module at some point?

agentrickard’s picture

Status: Postponed » Fixed

There is no domain-7.x.-1.x. Do you mean 7.x-3.x?

I don't know if I will include it here or not. It isn't a problem I have to deal with regularly, and -- for now at least -- having it separate means faster bug fixes and feature development.

Awesome work.

bforchhammer’s picture

Status: Postponed » Fixed

There is no domain-7.x.-1.x. Do you mean 7.x-3.x?

Sorry that was a typo; I meant the 3.x branch of course. :)

Status: Fixed » Closed (fixed)

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