多语言支持是Drupal的重要特点,也是我们选择Drupal的重要原因,我们开发的Drupal网站很多都是带有多语言的,这其中就需要放置多个语言之间的互相链接,我们开始是使用的Language Icons第三方模块,后来又在手机版和响应式设计中使用了Language Switcher Dropdown,一直到现在。
最近在转UTF8MB4支持的过程中,把一些老旧的MyISAM引擎表转为了InnoDB引擎,应该更强大,但我们应用的场景是读取远远大于写入,不能很好发挥InnoDB的优势,反而在数据统计方面表现比MyISAM更慢,引起阿里云RDS负载(特别是IOPS)升高,需要进行一些优化调整,在RDS参数尽量调整后还得看Drupal本身的优化。
以前使用Devel的时候发现过页面中有很多drupal_lookup_path的SQL语句,这次又仔细查看,一个典型多语言网站页面大约有100个SQL查询,其中居然有差不多50个drupal_lookup_path,这是因为我们有些站加了50种多语言支持,在语言切换这个Block中需要计算各种语言的链接地址,就产生了如此多的drupal_lookup_path,虽然每个执行时间很短,但数量也太多了一些。前几天想过一个办法《减少Drupal网站path查找数据库查询负载》,不是很正规,几天后又尝试了下面的办法。
我们的“多语言”网站并非严格意义上的每种语言都有不同内容、不同网址,而是都采用了'und'未定义语言的方式,存储内容和网址后面部分都是一样的,只是显示模板和网址前缀上有不同。所以完全可以抛弃标准多语言链接切换的第三方模块,而是自己来做一个这种多语言链接Block,一个页面可以减少几十次的drupal_lookup_path查询。
可以直接在网站中创建Block并输入PHP代码来实现,也可以使用自定义模块中添加Block定义的方式,后者代码实例如下:
function my_module_block_info() { $blocks=array(); $blocks['language_switcher']=array( 'info'=> t('Language').' '.t('Switcher'), 'cache'=>DRUPAL_NO_CACHE, 'weight'=>0, 'status'=>1, 'region'=>'sidebar_first', 'visibility'=>BLOCK_VISIBILITY_NOTLISTED, 'pages'=>'', ); return $blocks; } function my_module_block_view($delta = '') { $block=array(); switch($delta){ case 'language_switcher': $block['subject'] = t('Languages').' 🌐'; if(user_access('access content')){ $server_name=$_SERVER['SERVER_NAME']; $request_uri=$_SERVER['REQUEST_URI']; $languages = language_list('enabled'); $languages_array = $languages[1]; $language_default = language_default($property = 'language'); global $language; $language_current = $language->language; $language_name = $language->name; $language_native = $language->native; //$output = "<form action='$request_uri' method='post'>\n"; $output = ''; $output .= "<select style='width:165px' name='language_switcher_select' onChange=\"window.open(this.options[this.selectedIndex].value,'_self')\">\n"; if ($language_current == $language_default) { $request_uri_without_language = $request_uri; } else { $request_uri_without_language = substr($request_uri,strlen($language_current)+1); } if ($request_uri_without_language == '') $request_uri_without_language = '/'; foreach($languages_array as $key => $value) { $value_native = $value->native; if ($key == $language_current) { $output .= "<option value='$request_uri' selected='selected'>$value_native</option>\n"; } else { if ($key == $language_default) { $request_uri_new = $request_uri_without_language; } else { $request_uri_new = "/$key$request_uri_without_language"; } $output .= "<option value='$request_uri_new'>$value_native</option>\n"; } } $output .= "</select>\n"; $output .= "<img src='/sites/all/modules/languageicons/flags/$language_current.png' width='16' height='12' alt='$language_native' title='$language_name' />\n"; //$output .= "<noscript><input type='submit' name='op' value='Go' /></noscript>\n"; //$output .= "</form>\n"; $block['content']=$output; } break; default: } return $block; }
上面是我在自定义模块my_module.module中写的Block定义,在实际中测试了可以使用,语言切换功能与第三方模块的基本一致,SQL语句减少了很多。
评论