Problem/Motivation
nginx configuration is not accessible on the Pantheon platform to be able to rewrite the gtranslate urls.
Steps to reproduce
Attempt sub directory installation on the Pantheon platform.
Proposed resolution
Maybe there is a way to incorporate the tasks that the gtranslate.php script needed in the root into the module itself.
Following up on the issue here:
https://www.drupal.org/project/gtranslate/issues/3188348#comment-13957237 β
with some inspiration from here:
https://github.com/Pantheon-SE/pantheon-htaccess-rewrites/blob/master/pa...
I was able to get things working from what I can tell on Pantheon for the 8.x versions.
Pantheon does not allow access to the nginx configuration so rewriting the urls is not possible.
Two things were needed alongside the normal instructions for gtranslate:
- Rewriting code in settings.php
- Utilization of hook_css_alter to keep css urls from being changed during translation processing
The first step was to add the following to the Pantheon projects settings.php. I did this at the beginning of the file. Of course replace parts of this with appropriate domains etc.
// Non-pantheon environment setting if needed
if (!defined('PANTHEON_ENVIRONMENT')) {
$settings['gdomain'] = 'http://{localdomain.com}';
}
// Pantheon Env Specific gtranslate domains
if (isset($_ENV['PANTHEON_ENVIRONMENT'])) {
switch ($_ENV['PANTHEON_ENVIRONMENT']) {
case 'dev':
$settings['gdomain'] = 'https://dev-{site}.pantheonsite.io';
break;
case 'test':
$settings['gdomain'] = 'https://test-{site}.pantheonsite.io';
break;
case 'live':
$settings['gdomain'] = 'https://www.example.org';
break;
default:
// Multidev catchall
break;
}
}
/**
* Gtranslate redirect rules.
*/
$languages = 'af|sq|am|ar|hy|az|eu|be|bn|bs|bg|ca|ceb|ny|zh-CN|zh-TW|co|hr|cs|da|nl|en|eo|et|tl|fi|fr|fy|gl|ka|de|el|gu|ht|ha|haw|iw|hi|hmn|hu|is|ig|id|ga|it|ja|jw|kn|kk|km|ko|ku|ky|lo|la|lv|lt|lb|mk|mg|ms|ml|mt|mi|mr|mn|my|ne|no|ps|fa|pl|pt|pa|ro|ru|sm|gd|sr|st|sn|sd|si|sk|sl|so|es|su|sw|sv|tg|ta|te|th|tr|uk|ur|uz|vi|cy|xh|yi|yo|zu';
$matches = [];
$uri = parse_url($_SERVER['REQUEST_URI']);
$path = $uri['path'];
$settings['glang_info'] = parse_url($_SERVER['HTTP_HOST']);
if (preg_match("/^\/($languages)\/($languages)\/(.*)$/", $path, $matches)) {
header('HTTP/1.0 301 Moved Permanently');
header('Location: https://' . $_SERVER['HTTP_HOST'] . "/" . $matches[1] . '/' . $matches[3]);
exit;
}
$qs = '';
$matches = [];
if (preg_match("/^\/($languages)\/(.*)$/", $path, $matches)) {
if (!file_exists($matches[1] . '/' . $matches[2])) {
// get translation from script at root
$url = 'https://' . $_SERVER['HTTP_HOST'] . "/gtranslate/gtranslate.php?glang=". $matches[1] . '&gurl=' . $matches[2] . $qs;
// get_proxy_page will return the content we need
$page = get_proxy_site_page($url);
echo $page['content'];
exit();
}
}
$matches = [];
if (preg_match("/^\/($languages)$/", $path, $matches)) {
header('HTTP/1.0 301 Moved Permanently');
if (!empty($_SERVER['QUERY_STRING'])) {
$qs = '?' . $_SERVER['QUERY_STRING'];
}
header('Location: https://' . $_SERVER['HTTP_HOST'] . $path . '/' . $qs);
exit;
}
/**
* Proxy page request function. DO NOT EDIT OR REMOVE THIS FUNCTION!
*
* @param [string] $url
* @return void
*/
function get_proxy_site_page($url)
{
$options = [
CURLOPT_RETURNTRANSFER => true, // return web page
CURLOPT_HEADER => false, // return headers
CURLOPT_FOLLOWLOCATION => true, // follow redirects
CURLOPT_ENCODING => "", // handle all encodings
CURLOPT_AUTOREFERER => true, // set referer on redirect
CURLOPT_CONNECTTIMEOUT => 120, // timeout on connect
CURLOPT_TIMEOUT => 120, // timeout on response
CURLOPT_MAXREDIRS => 10, // stop after 10 redirects
];
$ch = curl_init($url);
curl_setopt_array($ch, $options);
$remoteSite = curl_exec($ch);
$header = curl_getinfo($ch);
curl_close($ch);
$header['content'] = $remoteSite;
return $header;
}
The next step was to add the following to a custom module in the .module file.
This is where the "gdomain" variable was needed from settings.php. From what I can tell, the gtranslate.php script replaces pretty aggressively any href="/..." to href="/{lang}/..." which fails for css files. Making the css url absolute keeps them from being replaced but allows menu links to get the appropriate language prefix.
This does mess with aggregation though as it makes the files "external". There may be a better way to handle this issue.
/*
* hook_css alter
* used to fix the css files that get changed by gtranslate
* making them full domain urls keeps gtranslate from changing the href value
* we need styles to not include the language part because that stops them from loading
* NOTE: This does seem to mess with aggregation because these assets are now "external"
*/
function mymodule_css_alter(array &$css, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
/*
The gdomain is what we are using and that comes from settings.php based on
pantheon environments
*/
$http_host = Settings::get('gdomain', '');
foreach($css as $key => $value) {
if( $css[$key]['type'] == 'file' ) {
$css[$key]['type'] = 'external';
$css[$key]['data'] = $http_host . '/' . $css[$key]['data'];
}
}
}
Once this was all done, the site was able to change languages via the block and stay on the chosen language prefix as the user navigates the site.
Admittedly I don't understand everything going on with this module this was just what ended up working for me on Pantheon.