【问题标题】:Programmatic Views in Drupal 7Drupal 7 中的程序化视图
【发布时间】:2011-04-12 17:37:31
【问题描述】:

我正在尝试创建两个视图。

View-1 是一个节点列表。

View-2 是与每个节点关联的图像库。

我基本上想将节点标题从 View-1 传递给程序化 View-2,以便 View-1 中的每一行都将加载 View-2(结果集由 View-1 的标题过滤!) .

我对这种方法感到困惑。这应该发生在自定义模块、预处理函数还是它们的某种组合中?

我经常遇到这种情况 - 想要将参数从主视图传递到与每个结果一起显示的辅助视图。

我意识到这个问题有点笼统,但我很好奇有更多经验的人会如何解决这个问题。

【问题讨论】:

    标签: drupal architecture drupal-views drupal-theming


    【解决方案1】:

    我之前在 D6 上做过这个,基本上我只是为我的 View-1 创建了几个模板 tpl.php 文件。

    在用于显示输出的 View-1 模板中(现在 D7 中的views-view--default.tpl.php) 我会简单地以编程方式查找 View-1 为该行传递或返回的值。

    在您的每一行的情况下,您将检查 View-1 返回哪个节点,然后我会在我的 View-1 模板中添加代码以基于当前 View-1 行以编程方式加载 View-2(即你的情况下的节点。)

    有意义吗?回复晚了 5 个月,但我一直在寻找复习,看看现在在 D7 中是否有更好的方法来做到这一点。

    更新
    刚刚在我的新 D7 安装中执行此操作。作为一个例子,我将解释它与我的 Ubercart 实现的关系。

    Ubercart 安装后,其主“主页”商店页面位于 mysite.com/catalog

    此页面在加载时会调用由 Ubercart 创建的名为 uc_catalog_terms 的视图。这是一个基于分类的视图,它所做的只是抓取所有目录分类并呈现它们。

    例如

    作为一家服装店,当您导航到mysite.com/catalog 时,您将在此页面上看到的只是一个网格结构,例如:

    毛衣 衬衫 牛仔裤

    我的要求是我需要在此页面上显示商店目录类别/术语,但 ALSO 在每个目录类别下方显示该类别/术语中的 3 个随机产品(图像)。

    例如

    毛衣
    随机毛衣 #1 - 随机毛衣 #2 - 随机毛衣 #3

    牛仔裤
    随机牛仔裤 #1 - 随机牛仔裤 #2 - 随机牛仔裤 #3

    这是如何实现的?

    我创建了自己的全新自定义视图(没有页面或锁,只是默认),它基于 分类术语 ID 参数抓取 3 个随机产品图像并呈现 3 个链接的产品图像。我将此自定义视图称为random_catalog_items。如果 15 是 Sweaters 的术语 ID,当使用参数 15 调用此视图时,它只会呈现 3 个随机链接的毛衣产品图像。

    我现在回到uc_catalog_terms 视图并创建了一个views-view-fields--uc-catalog-terms.tpl.php(行样式输出)模板文件。

    此文件的默认查看版本(修改前)是:

    <?php foreach ($fields as $id => $field): ?>
      <?php if (!empty($field->separator)): ?>
        <?php print $field->separator; ?>
      <?php endif; ?>
    
      <?php print $field->wrapper_prefix; ?>
        <?php print $field->label_html; ?>
        <?php print $field->content; ?>
      <?php print $field->wrapper_suffix; ?>
    <?php endforeach; ?>
    

    修改版变为:

    <?php foreach ($fields as $id => $field): ?>
      <?php if (!empty($field->separator)): ?>
        <?php print $field->separator; ?>
      <?php endif; ?>
    
      <?php print $field->wrapper_prefix; ?>
        <?php print $field->label_html; ?>
        <?php
            $title = str_replace('/','-',strtolower($field->raw));
            print '<img src="'.drupal_get_path('theme','my_theme').'/images/catalog/'.$title.'-header.png" />';
            print '<hr style="width: 100%; background: #000; height: 2px; margin-top: 3px;"/>';
            // get the taxonomy term ID 
            $tid = $row->tid;
            // render the 3 random items
            if ($random_products = views_get_view('random_catalog_items' )) {
                print $random_products->execute_display('default', array($tid));
            }
    
        ?>
      <?php print $field->wrapper_suffix; ?>
    <?php endforeach; ?>
    

    正如您在第一个视图中看到的那样,对于呈现的每一行,我都会通过可用的行结果对象 - $row-&gt;tid 显示当前分类术语 ID,然后我只需为每一行调用我创建的视图,传递这个术语 ID 作为它的参数。我在那里留下了很多默认代码,但在我的视图配置中,标签等设置为 HIDDEN,因此它们甚至都不会渲染。

    在您的情况下,它应该很容易适应只传递节点 NID 而不是分类术语 ID。

    瞧,一切正常!在视图中查看!希望这会有所帮助:)

    从那时起,在这些视图模板中加载开发模块会有所帮助,您可以通过print krumo($row) 之类的方式进行调试并查看哪些变量可供您使用。

    【讨论】:

    • 这听起来像我正在寻找的 - 你能提供一个代码 sn-p 从加载到不同模板的视图中调用变量的样子吗?
    • 刚刚更新了完整的用例示例和代码。希望能帮助到你。 @starsinmypockets
    【解决方案2】:

    就我个人而言,我会完全避免这里的观点。

    一个使用hook_menu 定义菜单项的简单模块和两个处理所需参数的简单菜单回调函数

    另一种方法是让视图知道所有自定义参数和自定义查询过滤和表。

    我的(个人)经验法则是:

    • 如果您确定会在以后的项目中多次重复使用代码,那么值得投资的视图插件。
    • 如果您将视图界面用于一次性设置(一般用途),例如在编辑/网站管理员工作流程中定义或更改视图,这是有道理的。

    这方面的基础非常简单,而且很可能比编写视图扩展少了很多编码和开发。

    /** Implementation of hook_menu().
     */
    function gallery_menu() {
      $items = array();
    
      $items['gallery'] = array(
        'title'            => 'Gallery',
        'page callback'    => '_gallery_list',
        'access arguments' => array('access content'),
      );
    
      $items['gallery/%gallery'] = array(
        'title'            => 'For dynamic titles, see title_callback documentation',
        'page callback'    => '_gallery_view',
        'access arguments' => array('access content'),
      );
    
      return $items;
    }
    
    /** Load a gallery from database. Name follows %parameter_load hook.
     */
    function gallery_load($id) {
      return db_query("SELECT * FROM {galleries} WHERE id = %d", $id);
    }
    
    /** Render a list of galleries.
     */
    function _gallery_list() {
      $html = "";
      $galleries = pager_query("SELECT * FROM {galleries}", 10);
    
      foreach($galleries as $gallery) {
        $html .= check_plain($gallery->title); //You would actually build vars here and push them to theme layer instead.
      }
      $html .= theme("pager");
      return $html;
    }
    
    /** Load a gallery from database. Name follows %parameter_load hook.
     */
    function gallery_load($id) {
      return db_query("SELECT * FROM {galleries} WHERE id = %d", $id);
    }
    
    /** Render a list of galleries.
     */
    function _gallery_view($gallery) {
      $html = "";
      $images = pager_query("SELECT * FROM {images} WHERE gallery_id = %d", 10, $gallery->id);
    
      foreach($images as $image) {
        $html .= check_plain($image->title); //You would actually build vars here and push them to theme layer instead.
      }
      $html .= theme("pager");
      return $html;
    }
    

    显然,如 cmets 中所述,您将另外创建一些主题函数来处理渲染,以 1)避免在您的模块中使用硬编码 spagetty-HTML 以及 b)允许前端在创建HTML。

    【讨论】:

      【解决方案3】:

      这听起来像是一个使用 ajax 回调的好机会。您可以像正常一样在页面的一部分上拥有主要视图,而在自定义块或其他内容中拥有次要视图。当焦点落在主要项目上时(以按钮单击或悬停或其他形式),您可以使用 ajax 回调使用您的参数将自定义块的内容替换为辅助视图。

      您使用的是 drupal 6 还是 7?我的理解是他们这样做的方式不同。

      【讨论】:

        猜你喜欢
        • 2012-03-09
        • 1970-01-01
        • 2011-11-06
        • 2023-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-30
        相关资源
        最近更新 更多