Adicionando uma sugestão de tema programaticamente

8

Eu criei um módulo de recurso contendo apenas uma visualização e um tipo de conteúdo.

No momento, meus page-node-x.tpl.phpe meus views-view-y.tpl.phparquivos estão no diretório de temas.

É possível movê-los para o meu módulo de recursos?

jantimon
fonte

Respostas:

5

Um módulo que implementa hook_preprocess_page()ou hook_preprocess_node()pode sugerir novos arquivos de modelo alterando a variável $variables['theme_hook_suggestions'].

O código contido em template_preprocess_page () que inicializa essa variável é o seguinte.

// Populate the page template suggestions.
if ($suggestions = theme_get_suggestions(arg(), 'page')) {
  $variables['theme_hook_suggestions'] = $suggestions;
}

Cada sugestão de tema precisa corresponder a uma entrada retornada por hook_theme () .

No Views, deve haver uma função de pré-processo equivalente para usar da mesma maneira, ou uma maneira que permita hook_preprocess_page()que a função entenda se a página está associada a uma view.

kiamlaluno
fonte
3

A solução para adicionar a chave 'arquivo de modelo' hook_views_api()ainda não parece funcionar no Drupal 7. No entanto, isso funciona como um encanto:

/**
 * Implements hook_theme().
 */
function bigtexas_theme() {
  return array(
    'views_view_fields__slideshow' => array(
    'variables' => array('view' => NULL, 'options' => NULL, 'row' => NULL),
    'template' => 'views-view-fields--slideshow',
    'base hook' => 'views_view_fields',
    'path' => drupal_get_path('module', 'bigtexas') . '/theme',
  ),
 );
}
Joe Hyde
fonte
2

O registro de temas é onde o Drupal armazena todos os tipos de informações sobre quais arquivos de modelo, funções de tema, etc, usar. Mexer com isso pode levar ao WTF momentos mais tarde, pois as coisas não funcionarão como padrão.

De qualquer forma, como todas as coisas drupal, existe um gancho: hook_theme_registry_altervocê pode usar para alterar o registro do tema e isso mover seus arquivos de modelo para um módulo. Eu não recomendaria isso, pois isso tornará a manutenção do site mais complexa. Mas se você quiser fazer isso, é assim que é feito.

googletorp
fonte
+1 - Eu tentei isso, mas sem sucesso .. Você poderia dar um exemplo?
jantimon
@ Ghommey: O link fornecido vem com um código de exemplo, não sei como explicar melhor.
googletorp
2

Para visualizações, existe em teoria um mecanismo para modelos de visualizações (talvez funcione para todos os modelos).

Você pode definir a chave "caminho do modelo" na sua implementação hook_views_api do seu módulo personalizado.

Depois de ter essas visualizações, o diretório especificado irá procurar arquivos de modelo. Infelizmente, o mais simples atualmente falha, portanto esse recurso provavelmente ainda não foi portado para o drupal7, mas se alguém quiser entrar nele, consulte _views_find_module_templates () em views.module.

Daniel Wehner
fonte
2

A maneira mais fácil é usar hook_theme_registry_alter()e adicionar o caminho do seu módulo aos caminhos do tema:

function mymodule_theme_registry_alter(&$theme_registry) {
  $theme_registry['[theme hook name, ie. page or views-view]']['theme paths'][] = drupal_get_path('module', 'mymodule');
}
Damien Tournoud
fonte
Olhando para a theme()implementação, não parece que theme pathpossa ser uma matriz. Tem certeza de que isso funciona? Veja api.drupal.org/api/drupal/includes%21theme.inc/function/theme/7
Capi Etheriel
Com relação ao meu comentário acima: theme pathscostumava trabalhar no Drupal 6, mas o Drupal 7 mudou esse comportamento em drupal.org/node/678714 Parece que, nos comentários # 29 e # 31 da edição mencionada, as sugestões de temas dos módulos precisam ser declaradas no hook_theme desse módulo, mas como fazer isso é deixado como um exercício para o leitor: /
Capi Etheriel
1

Que tal uma abordagem um pouco abstrata com o Tema de reação do contexto?

http://drupal.org/project/context_reaction_theme

Agrupe seu contexto em Recursos e é até exportável. Mas talvez essa seja realmente uma pergunta do guru Drupal que procura criar algo mais profundo e conhecer o caminho.

doublejosh
fonte
Não há módulo D7 e o último commit foi realizado há meio ano.
jantimon
Ainda funciona muito bem em meus Drupal 6 locais :)
doublejosh
1

Comecei com a resposta do googletorp e criei uma função genérica:

/**
 * Overrides a third-party template file with a local copy.
 *
 * To be called from hook_theme_registry_alter():
 * @code
 * function mymodule_theme_registry_alter(&$theme_registry) {
 *   // Override variant of foo template using local copy.
 *   custom_override_template($theme_registry, 'foo--variant', drupal_get_path('module', 'mymodule') . '/templates');
 * }
 * @endcode
 *
 * @param array $theme_registry
 *   Theme registry array as passed to hook_theme_registry_alter().
 * @param string $template
 *   Name of template file without '.tpl.php' extension. Example: 'foo--variant'.
 * @param string $path
 *   Directory to load $template from.
 * @param string $preprocess_function
 *   Optional preprocess function.
 */
function custom_override_template(&$theme_registry, $template, $path, $preprocess_function = NULL) {
  if (strpos($template, '--') !== FALSE) {
    $hook_name = array_shift(explode('--', $template));
  }
  else {
    $hook_name = $template;
  }
  $hook_name = str_replace('-', '_', $hook_name);
  if (isset($theme_registry[$hook_name])) {
    // Copy hook info.
    $hook_info = $theme_registry[$hook_name];
    $hook_info['path'] = $path;
    $hook_info['template'] = $template;
    // Add to theme registry.
    $new_hook = str_replace('-', '_', $template);
    $theme_registry[$new_hook] = $hook_info;
    // Add preprocess function.
    if(!is_null($preprocess_function)){
      $theme_registry[$new_hook]['preprocess functions'][] = $preprocess_function;
    }
    return $new_hook;
  }
  else {
    throw new Exception(t('Unknown theme hook %hook.', array('%hook' => $hook_name)));
  }
}

Ele permite não apenas sobrescrever a posição e o nome do nó e visualizar os arquivos tpl, mas também fornecer uma função de pré-processo para as visualizações.

Portanto, se você tiver seu próprio módulo chamado mymodulecom um arquivo de modelo, por exemplo, sites/all/modules/mymodule/templates/foo--variant.tpl.phpagora poderá modificar facilmente o registro do tema para usar seu próprio diretório de modelos:

function mymodule_theme_registry_alter(&$theme_registry) {
   // Override variant of foo template using local copy.
   custom_override_template($theme_registry, 'foo--variant', drupal_get_path('module', 'mymodule') . '/templates');
}
jantimon
fonte
Isso força o Drupal a usar o modelo na pasta do módulo. Um tema não poderá substituí-lo (como deveria ser).
jcisio
1

Como o @jcsio disse, a resposta aceita nesta página funciona, mas o modelo não pode ser substituído por um tema.

http://www.metachunk.com/blog/adding-module-path-drupal-7-theme-registry oferece uma solução que permite adicionar o caminho do seu módulo (e subpastas) a serem verificados para todos os tipos de arquivos .tpl.php.

Eu mudei um pouco, pois continha uma variável 'caminhos de tema' que parece não ser usada pelo Drupal 7.

/**
 * Implements hook_theme_registry_alter()
**/
function mymodule_theme_registry_alter(&$theme_registry) {
  $mod_path = drupal_get_path('module', 'mymodule');
  $theme_registry_copy = $theme_registry;       // munge on a copy
  _theme_process_registry($theme_registry_copy, 'phptemplate', 'theme_engine', 'pow', $mod_path);
  $theme_registry += array_diff_key($theme_registry_copy, $theme_registry);
}

Eu tentei a resposta aceita e esta solução, a última funciona para mim até agora!

lmeurs
fonte