Programowo umieszczać bloki?

14

Używam Drupal 7. Obecnie mam nawigację w menu głównym i przełącznik języka, który istnieje w nagłówku mojej witryny. Umieściłem je tam, przechodząc do CMS> Struktura> Bloki i przeciągając bloki do regionu nagłówka.

Jak programowo umieścić te bloki w nagłówku?

Jan
źródło
Zgodnie z pytaniem o sposób programowego umieszczenia tych bloków w nagłówku, sugeruję przejrzenie modułu Przykłady http://drupal.org/project/examples, a konkretnie możesz przejrzeć i włączyć moduł Przykład bloku, aby przetestować działanie bloku w sposób programowy . Sądzę, że ta block_example_block_info()wartość „regionu” może być przydatna do przetestowania.
cigotete,
John, czy znalazłeś odpowiedź na to pytanie?
powtórzyć

Odpowiedzi:

4

Aby zmienić region, w którym umieszczane są bloki zdefiniowane przez inne moduły, możesz zaimplementować hook_block_info_alter () , który otrzymuje następujące argumenty:

  • $blocks (przekazany przez referencję): tablica zawierająca definicje bloków, kluczowana przez moduł i deltę
  • $theme: temat, dla którego definiowane są bloki
  • $code_blocks: bloki zdefiniowane na podstawie hook_block_info()implementacji, zanim ich wartości zostaną zastąpione wartościami uzyskanymi z bazy danych
kiamlaluno
źródło
3

Uzasadnione jest dodanie tablicy renderowalnej do dowolnego regionu strony w hook_page_build (). Przykład Drupala 7, aby dodać minipanel do regionu stopki.

<?php
/**
 * Implements hook_page_build().
 */
function MODULE_page_build(&$page) {
  $block = module_invoke('panels_mini', 'block_view', 'blah');
  $blocks['blah'] = array('#markup' => $block['content']);

  $region = 'footer';
  if (isset($page[$region])) {
    $page[$region] = array_merge($page[$region], $blocks);
  }
  else {
    $page[$region] = $blocks;
  }
}

Jest to ta sama technika, która wykorzystuje moduł kontekstowy.

Uwaga: aby to zadziałało, nie potrzebujesz włączać block.module.

jonhattan
źródło
2

W D6 tak by było

$block = module_invoke("the_module_name", "block", "view", the_block_delta);
drupal_set_content("the_region_name", theme("block", $block));

W D7 tak myślę

$block = module_invoke("the_module_name", "block_view", the_block_delta);
drupal_add_region_content("the_region_name", theme("block", $block));

ale wciąż nabieram prędkości na D7.

mpdonadio
źródło
Nie pozwala to zewnętrznym modułom na zmianę wyjściowego bloku, ponieważ moduły mogą implementować hook_block_view_alter, który nie jest wywoływany z pokazanym kodem.
kiamlaluno
Uwierz drupal_add_region_content()to ślepy zaułek, ponieważ jest przeznaczony do stron instalacyjnych / aktualizacyjnych.
doublejosh
2

Jeśli dodajesz blok niestandardowy, robisz to za pomocą hook_block_info, ustawiając opcję statusu na 1, a opcję regionu na region, w którym chcesz umieścić blok.

Przykład:

MODULE_block_info() {
  $blocks = array();
  $blocks['my_block'] = array(
    'info' => t('My Block Name'),
    'status' => 1,
    'region' => 'THE_REGION_I_WANT',
   );
   return $blocks;
}

Jeśli chcesz zmienić już istniejący blok, użyj zamiast tego hook_block_info_alter (), aktualizując te same opcje, jak pokazano poniżej.

Przykład:

MODULE_hook_block_info_alter(&$blocks, $theme, $code_blocks) {
  $blocks['my_block']['status'] = 1;
  $blocks['my_block']['region'] = 'THE_REGION_I_WANT';
}

Aby uzyskać więcej informacji, zobacz https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7

Wesley J.
źródło
0

Ten kod jest oparty na kodzie @ jonhattan, ale jego nie renderuje HTML kontenera bloku ani łączy kontekstowych. Podałem również prosty sposób na określenie wszystkich bloków i regionów w jednym miejscu.

<?php
/**
 * Implements hook_page_build().
 */
function MODULE_page_build(&$page) {
  global $theme;

  // A list of blocks you wish to display, keyed by region.
  // These are in the format of: 'module_name' => 'delta'.
  $blocks_to_render = array(
    'header' => array(
      'block' => 1,
    ),
  );

  // Add the blocks to each region.
  foreach ($blocks_to_render as $region => $block_list) {
    $block_objects = array();
    foreach ($block_list as $module_name => $delta) {
      $block = block_load($module_name, $delta);
      // Alter some of the defaults to match the current context.
      $block->theme = $theme;
      $block->region = $region;
      $block->weight = 0;
      $block_objects[] = $block;
    }
    $blocks_build = _block_get_renderable_array(_block_render_blocks($block_objects));

    if (isset($page[$region])) {
      $page[$region] = array_merge($page[$region], $blocks_build);
    }
    else {
      $page[$region] = $blocks_build;
    }
  }
}

Uwaga: W przeciwieństwie do jego kodu, musisz zainstalować moduł block.module.

hargobind
źródło
-1

To nie jest najlepszą formą, ale można ręcznie umieścić zawartość do tablicy stron jak ten ...

function mymodule_page_alter(&$page) {
  $my_content = _mymodule_render_mycontent();
  $page['my_region']['my_special_insert']['content']['#markup'] = $my_content;
}

Chociaż powinieneś trzymać się kontekstu lub po prostu bloków rdzenia. Tworzenie nowych wtyczek nie jest tak złe, jak się wydaje. Wystarczy poprawnie nazwać pliki, skonfigurować wyzwalacz i test. przykładem .

doublejosh
źródło
W rzeczywistości, po drugiej myśli, prawie żałuję opublikowania tego rozwiązania. Nie rób tego
doublejosh,
-1

możesz także dostosować bloki w swoim motywie, takie jak:

/**
 * Implements hook_preprocess_page().
 */
function your_theme_preprocess_page(&$variables) {

  if (drupal_is_front_page()) {
    $variables['page']['region_one'] = $variables['page']['region_two'];
    unset($variables['page']['region_two']);
  }
}
rem
źródło
To nie odpowiada na pytanie, jak renderować bloki lub jak je identyfikować w znacznikach.
Christian