Drupal 7 - 使用hook_url _ * _ alter()进行URL重写似乎不起作用

时间:2011-10-28 09:41:58

标签: url-rewriting drupal-7 url-routing

这是我的情况:我在sites / default / files / pdf中有一堆HTML页面。我希望按原样提供服务,以便在Drupal网站上链接到它们。但是,其中一个要求是这些HTML页面的所有URL都不得包含任何扩展名。此外,我希望它以这样的方式运行:当用户访问example.com/sites/default/files/pdf/somehtmlfile时,URL将显示为example.com/pdf/somehtmlfile,以及用户访问示例时。将提供com / pdf / somehtmlfile,example.com/sites/default/files/pdf/somehtmlfile。

从我的独立研究来看,似乎我应该使用hook_url_inbound_alter()和hook_url_outbound_alter()。但是,我似乎做错了,因为URL根本没有改变。

以下是我的代码。我创建了一个名为html_extension_remover的模块(不是很有想象力的名字,我知道)。我已成功激活模块并且一些调试语句成功运行,因此我知道模块正在运行。

function html_extension_remover_url_outbound_alter(&$path, &$options, $original_path){
    $pdf_regex = '|^sites/default/files/pdf(/.*)?|';
    $pdf_new_path = 'pdf';

    if (preg_match($pdf_regex,$path, $matches)) //rewrite all request to sites/default/files/pdf to pdf, looks nicer
        if (count($matches)==1)
            $path = $pdf_new_path;
        else
            $path = $pdf_new_path . $matches[1]; //append the rest of the URL, after the Regex match
    if (strpos($path, $pdf_new_path)!=FALSE) //URL contains pdf, means viewing converted PDFs in pdf dir
        if (strpos($path, '.htm')!=FALSE){ //if viewing .htm/.html file
            $path = substr(0, strpos); //strip extension from URL
        }

    $pdf_new_path = 'sites/default/files/pdf';
    $pdf_regex = '|^pdf(/.*)?|';

    if (preg_match($pdf_regex, $path, $matches)){
        if (count($matches)==1){
            $path = $pdf_new_path;
        }
        else{
            $path = $pdf_new_path.$matches[1].'.htm';
        }
    }
}

function html_extension_remover_url_inbound_alter(&$path, &$options, $original_path){
    $pdf_new_path = 'sites/default/files/pdf';
    $pdf_regex = '|^pdf(/.*)?|';

    if (preg_match($pdf_regex, $path, $matches)){
        if (count($matches)==1){
            $path = $pdf_new_path;
        }
        else{
            $path = $pdf_new_path.$matches[1].'.htm';
        }
    }
}

1 个答案:

答案 0 :(得分:0)

如果我理解你正确的URL重写不是你需要的。为什么?因为将外部URL映射到某个内部URL /别名不会帮助您提供文件。

您需要的是让外部URL处理请求并返回相关文件的方法。幸运的是Drupal 7让这很容易做到。

1。)在hook_menu()

中定义菜单映射


    function MODULE_menu() {
      $items = array();
      $items['pdf'] = array(
        'title' => 'Map PDF',
        'page callback' => 'MODULE_show_pdf',
        'access callback' => TRUE,
        'description' => 'TBD',
        'type' => MENU_CALLBACK,
      );
      return ($items);
    }

2.。)定义你的回调函数



    function MODULE_show_pdf($somehtmlfile = '') {
      $stream_wrapper_uri = 'public://pdf/' . $somehtmlfile . '.pdf';
      $stream_wrapper = file_create_url($stream_wrapper_uri);
      $stream_headers = array(
        'Content-Type'      => file_get_mimetype($stream_wrapper_uri),
        'Content-Length'    => filesize($stream_wrapper_uri),
        'Pragma'            => 'no-cache',
        'Cache-Control'     => 'must-revalidate, post-check=0, pre-check=0',
        'Expires'           => '0',
        'Accept-Ranges'     => 'bytes'
      );              
      file_transfer($stream_wrapper_uri, $stream_headers);
    }

有些注意事项:

  1. 无需在菜单中明确定义somehtmlfile参数。这样您就可以更灵活地通过调整回调函数中的参数来简单地定义您希望此外部URL支持的任何参数。

  2. 当公共流包装器目录/文件是子站点:sites / default / files

  3. 假设你在网址中有一些你想要流式传输somehtmlfile.pdf(如果你想流式传输somehtmlfile.html,那么只需调整硬编码'.pdf'后缀)

  4. file_transfer调用drupal_exit()作为其最后一步,它基本上结束了请求处理。

  5. 确保刷新缓存,否则上述操作无效,因为缓存了菜单条目,无法找到外部URL