以编程方式更改活动Drupal主题的正确方法?


Answers:


15

Drupal 6解决方案:

您想确保$custom_theme在页面执行的早期就更改了全局变量。

global $custom_theme;
$custom_theme = 'garland';

hook_boot()和hook_init()可以在页面执行的早期(如果使用自定义模块)尝试几个钩子。
David Lanier

在哪里$custom_theme定义?是否足以更改主题?
Mohammad Ali Akbari 2012年


1
无法复制成功。:<
starlocke

为我工作。我在hook_boot()中
标记

15

我知道您问过如何以编程方式进行操作,但是如果这是您的解决方案,而不是实际的问题,则也可以使用ThemeKey模块。这使您可以设置条件,当条件满足时,可以更改主题。您可以根据路径,分类法,内容类型,创建或编辑日期等来创建条件。您还可以添加Themekey属性模块模块以获得更多选项。

同样,我知道这不是通过编程方式实现的,但是我不确定您问题背后的真正问题是否是如何根据条件更改主题。


4
是的,如果您想通过UI进行管理,建议您使用ThemeKey。
戴夫·里德


@Chaulky是正确的:一段时间以来,我一直在使用ThemeKey,这是根据用户名,角色,页面以及您想要的任何内容管理主题自定义设置的最简单方法。我推荐它。
Benj 2014年

14

最好的方法是在模块中创建更新挂钩:

function yourmodule_update_N() {
  variable_set('theme_default','yourtheme');
}

这应该是正确的答案..
尼克·贝瑞特

仅当您想全局更改主题时,这才是正确的。我从这个问题中假设,OP希望在特定页面或特定上下文中更改主题。
Evan Donovan

7

通过Drush更改活动主题

drush vset theme_default garland
drush vset admin_theme garland
drush cc all

通过模块更改活动主题

更改默认主题和管理主题的基础:

// Changes the theme to Garland
variable_set('theme_default', $theme_default);
// Changes the administration theme to Garland
variable_set('admin_theme', $admin_theme);

这是一个小功能,可以将主题安全地设置回默认的Drupal主题,例如Bartik或Garland(在Drupal 6和7中进行了测试):

/**
 * Set the active Drupal themes (the default and the administration theme) to default ones.
 * Tested in Drupal 6, 7 (but possibly working in version 8 too according to the documentations [some similarities between 7 and 8]).
 */
function TESTMODULE_set_active_theme_to_default($affect_admin_theme = TRUE) {

  // Provides a list of currently available themes.
  $list_themes = list_themes(TRUE);
  // 6, 7, 8, etc.
  $major_version = (int)VERSION;

  $theme_default = isset($list_themes['bartik']) ? 'bartik' : 'garland';
  $admin_theme   = isset($list_themes['seven']) ? 'seven' : 'garland';

  // Changes the theme to Garland
  variable_set('theme_default', $theme_default);

  // Changes the administration theme to Garland if argument is TRUE
  if($affect_admin_theme){
    variable_set('admin_theme', $admin_theme);
  }

  // if Switchtheme module (https://drupal.org/project/switchtheme) is enabled, use it
  if (module_exists('switchtheme')) {
    if (empty($_GET['theme']) || $_GET['theme'] !== $theme_default) {
      $query = array(
        'theme' => $theme_default
      );
      // in D6, drupal_goto's second argument is the query string,
      // in >=D7, a more general $options array is used
      if($major_version < 7){
        $options = $query;
      }
      else{
        $options = array('query' => $query);
      }

      drupal_goto($_GET['q'], $options);
    }
  }

  drupal_set_message(t('Default theme has been changed to %theme_default, administration theme has been changed to %admin_theme.', array(
    '%theme_default' => $theme_default,
    '%admin_theme' => $admin_theme
  )));

}

您可以在hook_init()实现中调用它(在不需要它时对其进行注释):

/**
 * Implements hook_init()
 */
function TESTMODULE_init() {  
  // ATTENTION! Comment out the following line if it's not needed anymore!
  TESTMODULE_set_active_theme_to_default();
}

这也是在安装配置文件中启用主题时将使用的方法variable_set('theme_default','yourtheme');
Duncanmoo

7

在Drupal 7中,使用hook_custom_theme()

/**
 * Implements hook_custom_theme()
 * Switch theme for a mobile browser
 * @return string The theme to use
 */
function mymodule_custom_theme()  {
    //dpm($_SERVER['HTTP_USER_AGENT']);
    $theme = 'bartik'; // core theme, used as fallback
    $themes_available = list_themes(); // get available themes
    if (preg_match("/Mobile|Android|BlackBerry|iPhone|Windows Phone/", $_SERVER['HTTP_USER_AGENT'])) {
        if (array_key_exists('custommobiletheme', $themes_available)) $theme = 'custommobiletheme';
        else { drupal_set_message("Unable to switch to mobile theme, because it is not installed.", 'warning'); }
    }
    else if (array_key_exists('nonmobiletheme', $themes_available)) $theme = 'nonmobiletheme';
    // else, fall back to bartik

    return $theme;
}

改编自<emoticode />

返回主题的机器可读名称,用于当前页面。

此功能的注释可能值得阅读:

该挂钩可用于动态设置当前页面请求的主题。需要基于动态条件覆盖主题的模块(例如,允许根据当前用户的角色设置主题的模块)应使用它。该钩子的返回值将在所有页面上使用,除了那些通过hook_menu()中的主题回调函数设置了有效的每页或每节主题的页面。这些页面上的主题只能使用hook_menu_alter()覆盖。

请注意,为同一路径返回不同的主题可能不适用于页面缓存。如果给定路径上的匿名用户在不同条件下可以返回不同的主题,则这很可能是一个问题。

由于一次只能使用一个主题,因此以从该挂钩返回有效主题名称的最后一个(即权重最高的)模块为准。


3

对于Drupal 8:

在settings.php中

$config['system.theme']['default'] = 'my_custom_theme';

以编程方式更新配置:

\Drupal::configFactory()
->getEditable('system.theme')
->set('default', 'machine_name')
->save();
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.