I have a menu item for one of my content types that I want to be able to package up some different files, create a .zip file, link to start a download and then display some text which will describe what the user needs to do with the .zip file.

Here is my menu declaration:

        'title' => 'Download Icon',
        'description' => 'Package up the selected icon as a zip file and download it',
        'page callback' => 'download_icon_page_callback',
        'page arguments' => array(1), 
        'access callback' => 'download_icon_access',
        'access arguments' => array(1), 
        'type' => MENU_LOCAL_TASK,

And here is my page callback that doesn't work for obvious reason:

function download_icon_page_callback()
    // some code to compile my .zip file
    return t('Here are some inustrctions!');

So this above function can link to the file compiled .zip with a drupal_goto but since this a redirect the return t will not ever go through. Is there anyway I can hit both of these in a single page callback? Also, is there a better way to display formatted text from the menu item instead of just doing a return t() from my page callback?

1 Answer 1


A particularly low-tech solution using meta refresh (which should work cross-browser):

function download_icon_page_callback() {
  $element = array(
    '#tag' => 'meta', 
    '#attributes' => array( 
      'http-equiv' => 'refresh',
      'content' => '5', // Timeout in seconds
      'url' => '/path/to/my/file.zip'

  drupal_add_html_head($element, 'download_icon_refresh');

  return array(
    'instructions' => array(
      '#markup' => t('Some instructions')
    'backup_link' => array(
      '#markup' => l('Click here if the file download does not automatically start.', 'path/to/my/file.zip'),
      '#prefix' => '<p>',
      '#suffix' => '</p>'

Although returning a string from a page callback function works fine (the return is run through render() which accepts a string or render array), returning a render array is preferred as it gives other parts of the system the chance to alter the output while it's still in a structured manner. The documentation for render arrays is a great place to start if you haven't used them before.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.