7.x system.api.php hook_page_alter(&$page)

Perform alterations before a page is rendered.

Use this hook when you want to remove or alter elements at the page level, or add elements at the page level that depend on an other module's elements (this hook runs after hook_page_build().

If you are making changes to entities such as forms, menus, or user profiles, use those objects' native alter hooks instead (hook_form_alter(), for example).

The $page array contains top level elements for each block region:


The 'content' element contains the main content of the current page, and its structure will vary depending on what module is responsible for building the page. Some legacy modules may not return structured content at all: their pre-rendered markup will be located in $page['content']['main']['#markup'].

Pages built by Drupal's core Node and Blog modules use a standard structure:

  // Node body.
  // Array of links attached to the node (add comments, read more).
  // The node object itself.
  // The results pager.

Blocks may be referenced by their module/delta pair within a region:

// The login block in the first sidebar region.


$page: Nested array of renderable elements that make up the page.

See also



Related topics

4 functions implement hook_page_alter()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

book_page_alter in modules/book/book.module
Implements hook_page_alter().
overlay_page_alter in modules/overlay/overlay.module
Implements hook_page_alter().
shortcut_page_alter in modules/shortcut/shortcut.module
Implements hook_page_alter().
system_page_alter in modules/system/system.module
Implements hook_page_alter().
1 invocation of hook_page_alter()
drupal_render_page in includes/common.inc
Renders the page, including all theming.


modules/system/system.api.php, line 1627
Hooks provided by Drupal core and the System module.


function hook_page_alter(&$page) {

  // Add help text to the user login block.
  $page['sidebar_first']['user_login']['help'] = array(
    '#weight' => -10,
    '#markup' => t('To post comments or add new content, you first have to log in.'),


onegenius’s picture

Go to configurations -> performance and refresh your cache after implementing this "hook_page_alter" if you want to see results.

goldhat’s picture

Lullabot has a podcast from Moshe Weitzman that discusses how to use this hook_page_alter, listen to it at http://www.lullabot.com/podcasts/drupal-voices-160-moshe-weitzman-on-pag...

agalligani’s picture

I have a node type called "innerpage" I created through the admin interface and I added a field called Link List (field_link_list) which is a list of links to anchor tags on the page. The links needed to be on the sidebar second. I could have made a block somehow I guess, but moving it to the sidebar was pretty easy... The code might help somebody.

function custom_page_alter(&$page) {
foreach($page['content']['system_main']['nodes'] as $nid => $nodes) { 			

if($page['content']['system_main']['nodes'][$nid]['body']['#bundle'] == 'innerpage') {
$page['content']['system_main']['nodes'][$nid]['field_link_list']['#label_display'] ='hidden'; 
$page['sidebar_second']['system_main']['nodes'][$nid]['field_link_list'] = 	$page['content']['system_main']['nodes'][$nid]['field_link_list'];

Now that I look at it I suppose I could have checked isset() on the field being in the array instead of checking for the node type from "#bundle", but for what I did it works. Maybe I'll change it in case I need to use the field on a different node type.

The simple trick for me was to foreach through the nodes in $page['content']['system_main']['nodes'] to get the nid. Seems obvious but I didn't see it anywhere in any examples. Maybe there is an easier method?

Hope it helps...

Alan D.’s picture

This code moves one block to the top of the second side bar region when viewing content of type blog.

function THEMENAME_page_alter(&$page) {
  if (isset($page['sidebar_second'])) {
    if ($node = menu_get_object()) {
      if ($node->type == 'blog') {
        if (isset($page['sidebar_second']['cck_blocks_field_resources'])) {
          $page['sidebar_second']['cck_blocks_field_resources']['#weight'] = -100;
          $page['sidebar_second']['#sorted'] = FALSE;

If you forget to set #sorted, chances are that the block will not float up the list

mkhamash’s picture

hook_page_alter have been removed from Drupal 8, for the change read Added hook_page_attachments(_alter)() and removed hook_page_build/alter().

hook_page_attachments(_alter) can be used to cover some of hook_page_alter use cases, but is only intended to add/edit assets and not changing the page content.

omrmankar’s picture

how to show any page content on any page using page alter please comment me the better solution for that.

ItangSanjana’s picture

Replace default message and it's title without promoting content to the front page.

 * Implements hook_page_alter().
function YOURMODULE_OR_YOURTHEME_page_alter(&$page) {
  // Replace default message and it's title.
  if (
    drupal_is_front_page() &&
  ) {
    $page['content']['system_main']['default_message']['#markup'] = '';

    // Check for the title.
    if (drupal_get_title()) {