Hi, the #1 question regarding translating Drupal 5.0 using installation profiles is:
And why do you say 100% is translated? I enabled blog module and it is not.
Is there a way to hook into blog.install (for example) and perform AUTOMATIC import of translation, using auto locale module? So user will not have to run Administer -> Locale -> Auto Import ?
I think this is the way we should focus now.
Jakub
Hi,
Jakub Suchy wrote:
Hi, the #1 question regarding translating Drupal 5.0 using installation profiles is:
And why do you say 100% is translated? I enabled blog module and it is not.
Is there a way to hook into blog.install (for example) and perform AUTOMATIC import of translation, using auto locale module? So user will not have to run Administer -> Locale -> Auto Import ?
I think this is the way we should focus now.
Indeed. I tried to get in a patch to Drupal 5 to support our implementation of these kind of features, but it was too late in the cycle, so it was rejected. We either need to duplicate the functionality from the module and theme admin pages, or we need to stick in two submit callbacks to the forms, one that runs early, and one that runs last, so we can see, what was changed in the database about modules (enabled/disabled/installed) and themes (enabled/disabled). That way, we can stick our process into the enable/disable flow.
As far as I see know, adding a pre-submit and a post-submit callback is the better way to go, as it involves less core code duplication (but more database magic).
Gabor
Indeed. I tried to get in a patch to Drupal 5 to support our implementation of these kind of features, but it was too late in the cycle, so it was rejected. We either need to duplicate the functionality from the module and theme admin pages, or we need to stick in two submit callbacks to the forms, one that runs early, and one that runs last, so we can see, what was changed in the database about modules (enabled/disabled/installed) and themes (enabled/disabled). That way, we can stick our process into the enable/disable flow.
As far as I see know, adding a pre-submit and a post-submit callback is the better way to go, as it involves less core code duplication (but more database magic).
Or submit a patch to module.inc something like hook_postinstall() using module_invoke_all?
Jakub Suchy wrote:
Indeed. I tried to get in a patch to Drupal 5 to support our implementation of these kind of features, but it was too late in the cycle, so it was rejected. We either need to duplicate the functionality from the module and theme admin pages, or we need to stick in two submit callbacks to the forms, one that runs early, and one that runs last, so we can see, what was changed in the database about modules (enabled/disabled/installed) and themes (enabled/disabled). That way, we can stick our process into the enable/disable flow.
As far as I see know, adding a pre-submit and a post-submit callback is the better way to go, as it involves less core code duplication (but more database magic).
Or submit a patch to module.inc something like hook_postinstall() using module_invoke_all?
It is not going to solve the problem for Drupal 5, since Drupal 5 is not going to have new features (eg. hooks) anymore. It is released, stable. It will get maintained but that does not mean any new hooks added, just errors corrected. This can be added into Drupal 6 though for which the whole autolocale (feature, not the actual code) is requested to be included anyway.
We need to find a way in Drupal 5 without core patching, and autolocale_form_alter()-ing the module and theme forms, adding an early and a last callback seems to do the trick:
1. Check the database (or the module_list()) in the early callback. 2. Check it again at the callback called last. 3. Compute the difference. 4. Import what needs to be imported
Unfortunately we cannot remove strings for disabled stuff, but we can look into this for Drupal 6.
See the stub is already in autolocale.module since a few weeks:
/** * Implementation of hook_form_alter() * * @todo * Alter system form to catch module enable/disable actions */ function autolocale_form_alter($form_id, &$form) { }
Gabor
Gabor Hojtsy wrote:
- Check the database (or the module_list()) in the early callback.
- Check it again at the callback called last.
- Compute the difference.
- Import what needs to be imported
Is this clean and does it have some catch? It works for me
function autolocale_form_alter($form_id, &$form) { // Process only if module form is displayed if ($form_id === "system_modules") {
// Determine which modules are enabled at the moment if (is_array($form['status']['#default_value'])) { $autolocale_modules = array(); foreach ($form['status']['#default_value'] as $module) { array_push($autolocale_modules, $module); }
// We MUST skip module confirm form if ($_GET['q'] != "admin/build/modules/list/confirm") { $enabled = array_diff($autolocale_modules, $_SESSION['autolocale_modules']); if (!empty($enabled)) { // These modules have been enabled print_r($enabled); // TODO } }
// Store modules for next reload $_SESSION['autolocale_modules'] = $autolocale_modules; }
} }
Well, I would not use a session for this task. It is (remotely) possible that two different admins access the module page simultaneosly, so you end up with stale data in the session about enabled modules, since inbetween modules can be enabled/disabled in another session. To get as close as possible, I would stuff a pre-submit callback into the form and a post-submit callback (ie. add a submit callback before the default submit callback and one after). You can do a select on enabled modules in the first callback, remember it (static function var). The second needs to do another select, ask for the static var from the first function and check the difference.
In an ideal world, it would be important that we should not only look at the status change (this is why the form array would not have enough information). If the status changed it only means that a module was enabled/disabled. But still, we don't know if a module was *installed* as part of being enabled, in which case the translations would import. Once a module is already installed, even if it is disabled, strings are kept in the database, so they should not be reimported (ie. because the user modified the translations) when reenabled.
Since we are not living in an ideal world, we would probably reload the strings into the database every time one module is enabled, but it would be good to keep the ideal situation in mind, so once this code gets into Drupal we have an already cleaner implementation and don't need to recode everything.
So, I would use two callback (not real function names :):
function autolocale_premoduleformsubmithandler($return = NULL) { static $module_data = array(); if (!isset($return)) { // SELECT module data (name, status field, schema_version) // stuff into $module_data; } else { return $module_data; } }
function autolocale_postmoduleformsubmithandler() { $pre_module_data = autolocale_premoduleformsubmithandler(TRUE); // SELECT module date (see above) // compare // import needed PO files }
I don't have time immediately to do it unfortunately, so help would be appreciated.
Gabor
On Thu, 18 Jan 2007, Jakub Suchy wrote:
Gabor Hojtsy wrote:
- Check the database (or the module_list()) in the early callback.
- Check it again at the callback called last.
- Compute the difference.
- Import what needs to be imported
Is this clean and does it have some catch? It works for me
function autolocale_form_alter($form_id, &$form) { // Process only if module form is displayed if ($form_id === "system_modules") {
// Determine which modules are enabled at the moment if (is_array($form['status']['#default_value'])) { $autolocale_modules = array(); foreach ($form['status']['#default_value'] as $module) { array_push($autolocale_modules, $module); }
// We MUST skip module confirm form if ($_GET['q'] != "admin/build/modules/list/confirm") { $enabled = array_diff($autolocale_modules, $_SESSION['autolocale_modules']); if (!empty($enabled)) { // These modules have been enabled print_r($enabled); // TODO } } // Store modules for next reload $_SESSION['autolocale_modules'] = $autolocale_modules;}
} } _______________________________________________ translations mailing list translations@drupal.org http://lists.drupal.org/mailman/listinfo/translations
Hi Jakub,
I have done away two hours this evening with trying to come up with ways to handle this without stuffing the module list into the session, but was unable to do it, since the system_module handler results in a redirect before a possible next submit handler would be able to run.
Anyway, after that two hours, I have started off from your code and cleaned it up (ie. no need to foreach on the form array, since we can grab it as is). Added logic to import all PO files for all enabled languages, and comitted the result:
http://drupal.org/cvs?commit=54356
I tried to test this as much as I can, and it really seems to work. After giving some deeper thought to this session storage method, I figured we have no problem with it until we need to deal with modules being disabled (which is not the case yet).
Thanks for sharing this piece of advice!
Ps. I also fixed a cache cleanup error, and a postresql compatibility error recently in autolocale.
Gabor
Jakub Suchy wrote:
Gabor Hojtsy wrote:
- Check the database (or the module_list()) in the early callback.
- Check it again at the callback called last.
- Compute the difference.
- Import what needs to be imported
Is this clean and does it have some catch? It works for me
function autolocale_form_alter($form_id, &$form) { // Process only if module form is displayed if ($form_id === "system_modules") {
// Determine which modules are enabled at the moment if (is_array($form['status']['#default_value'])) { $autolocale_modules = array(); foreach ($form['status']['#default_value'] as $module) { array_push($autolocale_modules, $module); } // We MUST skip module confirm form if ($_GET['q'] != "admin/build/modules/list/confirm") { $enabled = array_diff($autolocale_modules, $_SESSION['autolocale_modules']); if (!empty($enabled)) { // These modules have been enabled print_r($enabled); // TODO } } // Store modules for next reload $_SESSION['autolocale_modules'] = $autolocale_modules; }} } _______________________________________________ translations mailing list translations@drupal.org http://lists.drupal.org/mailman/listinfo/translations
Gabor, very nice work, thanks!
I found two little bugs, created patches and issued them:
1) When displaying module page for the first time, there is no $_SESSION['autolocale_modules'] yet.
2) Due to one security bug in PHP two years ago, glob() is disabled on many shared hosts. Therefore i suggest to use opendir(), search for files and save them to $files array.
I have also added one more is_readable() check to the code and added drupal_set_message(t('Imported translation file ' . basename($filepath)), 'status'); (Because user need to know something happened to his translations.
Jakub