Blöcke programmatisch platzieren?

13

Ich verwende Drupal 7. Im Moment habe ich eine Hauptmenü-Navigation und einen Sprachumschalter, die in meinem Website-Header vorhanden sind. Ich habe sie dort platziert, indem ich zu CMS> Structure> Blocks gegangen bin und die Blöcke in den Header-Bereich gezogen habe.

Wie positioniere ich diesen Block programmatisch im Header?

John
quelle
Entsprechend Ihrer Frage, wie Sie diesen Block programmgesteuert in der Kopfzeile anordnen können, empfehle ich das Modul "Beispiele" http://drupal.org/project/examples. Insbesondere können Sie das Modul "Blockbeispiel" überprüfen und aktivieren, um die programmgesteuerte Arbeitsweise Ihres Blocks zu testen . Ich vermute, dass block_example_block_info()der Wert "Region" nützlich sein könnte, um ihn zu testen.
Cigotete
John, hast du eine Antwort darauf gefunden?
Relipse

Antworten:

4

Um die Region zu ändern, in der von anderen Modulen definierte Blöcke platziert werden, können Sie hook_block_info_alter () implementieren , das die folgenden Argumente empfängt:

  • $blocks (als Referenz übergeben): Das Array mit den Blockdefinitionen, die nach Modul und Delta verschlüsselt sind
  • $theme: Das Thema, für das die Blöcke definiert werden
  • $code_blocks: Die aus den hook_block_info()Implementierungen definierten Blöcke , bevor ihre Werte von den aus der Datenbank erhaltenen Werten überschrieben werden
kiamlaluno
quelle
3

Es ist zulässig, in hook_page_build () jedem Seitenbereich ein renderbare Array hinzuzufügen. Drupal 7-Beispiel zum Hinzufügen eines Minipanels zur Fußzeilenregion.

<?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;
  }
}

Dies ist die gleiche Technik, die Kontextmodul verwendet.

Hinweis: Sie müssen block.module enable nicht aktivieren, damit dies funktioniert.

jonhattan
quelle
2

In D6 wäre es im Wesentlichen

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

In D7 denke ich schon

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

aber ich bin immer noch auf D7 auf dem Laufenden.

mpdonadio
quelle
Dies erlaubt es Modulen von Drittanbietern nicht , den ausgegebenen Block zu ändern, da Module hook_block_view_alter implementieren könnten , der nicht mit dem von Ihnen angezeigten Code aufgerufen wird.
kiamlaluno
Glauben drupal_add_region_content()ist eine Sackgasse, da es für die Installation / Aktualisierung von Seiten gedacht ist.
DoubleJosh
1

Wenn Sie einen benutzerdefinierten Block hinzufügen, verwenden Sie dazu hook_block_info und setzen die Statusoption auf 1 und die Regionsoption auf die Region, in die der Block eingefügt werden soll.

Beispiel:

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

Wenn Sie einen bereits vorhandenen Block ändern möchten, verwenden Sie stattdessen hook_block_info_alter (). Das Aktualisieren derselben Optionen wird unten gezeigt.

Beispiel:

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

Weitere Informationen finden Sie unter https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7

Wesley J
quelle
0

Dieser Code basiert auf @ jonhattans, rendert jedoch nicht den Blockcontainer-HTML-Code oder Kontextlinks. Ich stellte auch eine einfache Möglichkeit zur Verfügung, alle Blöcke und Regionen an einem Ort anzugeben.

<?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;
    }
  }
}

Hinweis: Im Gegensatz zu seinem Code muss das block.module installiert sein.

hargobind
quelle
-1

Dies ist nicht die beste Form, aber Sie können Inhalte wie folgt manuell in das Seitenarray einfügen ...

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

Sie sollten sich jedoch an die Verwendung von Context oder nur an Kernblöcken halten. Das Erstellen neuer Plugins ist nicht so schlimm, wie es scheint. Benennen Sie die Dateien einfach richtig, richten Sie einen Auslöser und einen Test ein. Beispiel .

doublejosh
quelle
Tatsächlich bereue ich es fast, diese Lösung veröffentlicht zu haben. Mach das nicht.
DoubleJosh
-1

Sie können auch Blöcke in Ihrem Thema anpassen wie:

/**
 * 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']);
  }
}
Rémy
quelle
Dies beantwortet nicht die Frage, wie Blöcke gerendert oder im Markup identifiziert werden sollen.
Christian