Drupal 7 中的程序化视图

发布于 2024-11-01 00:40:49 字数 301 浏览 1 评论 0原文

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

View-1 是节点列表。

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

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

我对这种方法感到困惑。这种情况应该发生在自定义模块、预处理函数或其某种组合中吗?

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

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

I'm trying to create two views.

View-1 is a list of nodes.

View-2 is an image gallery associated with each node.

I basically want to pass the node title from View-1 to a programmatic View-2, so that each row in View-1 will load View-2(with a result set filtered by the title of View-1!).

I'm confused about the approach. Should this happen in a custom module, preprocess functions, or some combination thereof?

I run into this a lot - wanting to pass an argument from a primary view to a secondary view that displays with each result.

I realize that the question is a bit general, but I'm curious how folks with more experience would approach this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

逐鹿 2024-11-08 00:40:49

我之前在 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 时,您在此页面上看到的只是一个网格结构,例如:

毛衣、衬衫、牛仔裤

我的要求是我需要展示商店此页面上有目录类别/术语,但在每个目录类别下方显示该类别/术语的 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; ?>

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

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

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

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

I've done this before on D6 where basically I just create a couple template tpl.php files for my View-1.

Inside my View-1 template for Display Output (views-view--default.tpl.php in D7 now)
I would simply programmatically find the value passed or returned by View-1 for this row.

In your case on each row you would check to see which node is returned by View-1 and then I'd add code in my View-1 template to programmatically load View-2 based on the current View-1 row (ie. node in your case.)

Make sense? 5 months late on the response but I was looking for a refresher and seeing if there's a better way to do this now in D7.

UPDATE:
Just did this on my new D7 install. As an example I'll explain how it relates to my Ubercart implementation.

Ubercart, when installed, has it's main "home" shop page located at mysite.com/catalog

This page, when loaded, calls a View created by Ubercart called uc_catalog_terms. It is a taxonomy based view and all it does is grab all your Catalog taxonomy categories and render them.

E.g

As a clothing store, when you navigate to mysite.com/catalog, all you'll see at this page is a grid structure like:

Sweaters Shirts Jeans

My requirement was that I needed to show the shop catalog categories/terms on this page, but ALSO show 3 random products (images) from that category/term below it each catalog category.

E.g

Sweaters
Random Sweater #1 - Random Sweater #2 - Random Sweater #3

Jeans
Random Jean #1 - Random Jean #2 - Random Jean #3

How is this accomplished?

I created my own brand new custom view (no page or lock, just default) which grabs 3 random product images based on a taxonomy term ID argument and renders 3 linked product images. I'll call this custom view random_catalog_items. If 15 is the term ID for Sweaters, when this view is called with the argument 15 it will only render 3 random linked sweater product images.

I now went back to uc_catalog_terms view and created a views-view-fields--uc-catalog-terms.tpl.php (Row Style Output) template file.

THE DEFAULT VIEW VERSION OF THIS FILE (BEFORE MODIFICATION) IS:

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

THE MODIFIED VERSION BECOMES:

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

So as you can see inside the first View, for every row that is rendered I get the current taxonomy term ID being shown through the available row result object - $row->tid and then I simply call my created view for each row, passing along this Term ID as the argument for it. I leave a lot of the default code in there but inside my view configurations the LABELS and such are set to HIDDEN so they don't even render anyway.

In your case it should be very easily adaptable to just pass a Node NID instead of a Taxonomy Term ID.

VOILA IT ALL WORKS! View within a View! Hope this helps :)

It helps to have the Devel module loaded since then inside these View templates you can debug and see what variables are available to you via something like print krumo($row).

终遇你 2024-11-08 00:40:49

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

一个简单的模块,使用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;
}

显然,正如评论中所述,您还需要创建一些主题函数来处理渲染,1)避免在整个模块中硬编码 spagetty-HTML,b)允许前端在创建 HTML 时保留其主题。

Personally I would avoid views here alltogether.

A simple module using a hook_menu to define the menu-items and two simple menu-callback-functions dealing with the required parameters.

The alternative would be to make all the custom parameters and custom query-filtering and tables known to views.

My (pseronal) rule of thumb is:

  • If you are certain you will re-use the code several times in future projects a view-addon is worth the investment.
  • If you will use the views-interface for more then one-time-setup (the general use) e.g. define or change views in an editors/webmasters workflow this makes sense.

The basics of this is really simple and most probably a lot less coding and development then writing the views extensions.

/** 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;
}

Obviously, as stated in the comments, you would additionally create a few theme functions to handle the rendering, to 1) avoid hardcoded spagetty-HTML all over your module and b) allow the frontenders to stay in their theme when creating the HTML.

怂人 2024-11-08 00:40:49

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

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

This sounds like a good opportunity to use an ajax callback. You could have your primary view on a part of the page just like normal and a secondary view in a custom block or something. when focus lands on the primary item (in the form of a button click or hover or something) you can use an ajax callback to replace the content of your custom block with the secondary view using your argument.

are you using drupal 6 or 7 for this? my understanding is that they do this is different ways.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文