当前位置

Drupal中自定义语言切换Block,减少页面SQL数量

James Qi 在 2017年11月20日 - 23:33 提交
内容摘要:多语言支持是Drupal的重要特点,也是我们选择Drupal的重要原因,我们开发的Drupal网站很多都是带有多语言的,这其中就需要放置多个语言之间的互相链接,我们开始是使用的Language Ico......

  多语言支持是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语句减少了很多。

自由标签: