我今天花了很多时间来扩展我继承的drupal网站,确信我面临的问题归结为我的定制SQL查询。
我已经意识到SQL是可以的(在PHPMYadmin中检查它并在drupal网站中执行各种操作)。所以我很高兴我从我需要的数据库中获取所有结果,循环遍历它们并在特定标记的页面上输出它们。
我遇到的问题是循环显示的位置。我似乎无法想象主题系统或了解template.php中发生了什么。
让我解释一下:
我需要更改的代码在template.php文件中。我的理解是这个文件允许你覆盖某些功能和主题元素。
在template.php文件中,这是我需要更改的代码:
//old function from original development
function abc($node,$submitted,$node_url) {
//execute code
}
所以我在函数abc()中添加了我的代码,因为我希望在输出旧代码的地方输出它。
这是我的sql和循环的伪代码:
function abc($node,$submitted,$node_url) {
$sql = 'my sql query'
$results =db_query($sql);
while ($data = db_fetch_array($results)) {
//output my results here
}
}
是什么让我相信sql错误的是我应该得到23个结果,但是我得到了更多重复的条目。浪费了很多时间在错误的地方,并仔细检查sql,我意识到这是执行sql和循环多次的函数,而不是sql返回重复的条目。我是这样做的:
function abc($node,$submitted,$node_url) {
$sql = 'my sql query'
$results =db_query($sql);
$x = 1;
while ($data = db_fetch_array($results)) {
if ($x == 1) {
echo '<p style="background-color:#ccc;">'. $x . '. '.$data['title'] . '</p>';
}else{
echo '<p>'. $x . '. '.$data['title'] . '</p>';
}
$x = $x + 1;
}
}
随着代码的执行,我希望增加的数字继续进行多次重复输入,并将第一个条目的背景变为灰色,但事实并非如此。在结果23,它将自身重置为1并将该条目的背景阴影显示为灰色,向我指示它是多次执行sql和循环的函数。
我不完全确定这个abc()函数是什么,除了当我将代码放入其中时,输出显示我需要它在特定页面上的其他位置(没有重复条目)
当我从我的代码中取出代码时(仍然在template.php中),我的代码输出在所有页面的头部,这是不可取的。
有没有人对可能发生的事情有任何想法,我可以在哪里找出这个功能是什么,或者知道如何确定我的代码显示方式?
我一直在阅读有关主题等的内容,但与其他人的代码合作正在变成一种混乱的噩梦。
提前干杯!
答案 0 :(得分:2)
你走错了路,可能是因为你对Drupal的工作方式缺乏经验,所以让我给你一些信息和建议。
你可以说Drupal必须在其中执行代码,模块/核心和主题的层。通常你可以说第一层,模块/核心是数据的生成/获取,而第二层是数据的表示。你正在做的是在表示层中获取数据,这是应该避免的。这也是为什么你在追踪原因方面遇到很多麻烦的原因,因为获取数据的内容和呈现数据的内容混淆了。你所做的也是非常浪费资源,我稍后会谈到,但首先发生了什么?
你已经接管了一个可能有自定义主题的网站,我可以说它是以一种黑客的方式制作的。也许那个做过它的人,不知道正确的方法,但做了一些“有效”的东西。现在正试图改变它,你打破了它。当Drupal呈现一个节点(一个节点是一段内容)时,它会获取大量数据,模块可以挂钩并添加,更改或删除该数据,最后数据到达模板(所有模板文件都是用tpl.php表示 - 除非使用不同的模板引擎。这种方式的工作方式是,它使用“页面”模板来创建网站的基础知识,导航,不同的区域等。现在,当显示节点列表时,通过将其数据输出到节点模板,每个节点将显示在页面模板中。通常有很多div等。结合一些php打印数据。在您的示例中,还调用了一个函数。在某些情况下,如果您为多语言网站使用fx翻译功能或为您检查某些内容的简单功能,这可能会很好。但是在您的情况下,您使用该函数来获取数据。通过查看您创建的SQL,您似乎确实想要获取要显示的博客节点列表。如果只显示一个节点,这可能会有效,但是当显示一个节点列表时,您运行SQL并打印列出的每个节点的结果,这就是让您陷入困境的原因。这也是非常无效的,因为每次使用节点模板时都会运行查询。正如您所看到的,在主题层中获取数据非常困难且难以控制。但那你怎么做呢?
有一些不同的方法来做事情,甚至为此做了模块。现在看来你想根据2个CCK日期字段显示博客节点列表
简单的非编码方式:
只需使用views模块创建一个视图。您可以选择基于博客和过滤器类型的节点以及当前数据和cck字段上的日期。您可以选择不同的显示。显示整个节点或仅显示节点,列表,表等的一部分。最后,您为视图选择了一个URL,您就完成了。
更难编码的方式:
创建自定义模块。首先,您需要实现hook_menu()来创建一个菜单项,这是您设置URL的方式。这样做可以指定必须为该URL创建的功能。在其中您放置了上述代码中的大部分代码,使用SQL获取数据,但是您还需要通过生成标记的各种主题函数运行该数据,最后返回数据。如果你知道Drupal是如何工作的,这实际上很容易做到。如果没有,将很难正确执行此操作,因为您需要调用许多您不知道的函数,并实现钩子等。
这最终比我计划的时间长了一些,但我希望它可以帮助你使用新的Drupal网站。
修改强>
实际上,您发布的SQL似乎是从一个看似有效的视图生成的SQL。唯一的缺陷是你要求两个日期字段大于或等于现在。 CCK字段可以具有默认值,但我相信您可以在编辑节点时始终将其编辑为您喜欢的任何内容,除非已编辑节点表单以隐藏字段。此外,没有任何理由在发布日期使用CCK日期字段。该信息可在每个节点上以及最后编辑的日期获得。
你可以在Lullabot找到很多好东西。他们在如何使用CCK和视图方面做了很多工作。其中一些是他们出售的,其中一些你可以免费获得。在您的示例中,困难的部分是获取所需的节点。为此,您需要添加过滤器。如果要按任何日期排序,则需要添加日期组中的日期过滤器。在其中,您可以检查要使用的字段。但是,在您的情况下,您希望为每个日期字段添加两次日期过滤器,因为您具有不同的字段值。这可能是你的缺陷所在,也是你遇到问题的原因。
答案 1 :(得分:1)
好吧,首先,你不应该使用echo
,因为它会在代码运行时打印(例如在页面顶部加载时),而不是模板显示的变量页面中的适当位置。 (这并不是说echo
不会永远工作,但使用它不是最佳做法。)
上一个函数用于输出数据的内容是什么? (可能有一个名为abc.tpl.php
的页面(如果您的函数名为abc
),它将帮助您找到合适的变量名称。
如果添加您正在使用的SQL字符串,我也可以诊断该问题。
编辑:
根据您之前的评论,假设您正在尝试格式化博客节点(我的基础是您提到缺少node-blog.tpl.php):
Drupal在渲染页面时的假设是这样的(简化):
加载核心。从数据库中获取内容。获取分类法和其他好东西,并将这些内容提供给模块和主题
然后,查看所有模块以查看 如果他们有钩子,基于 他们的功能名称,将修改 页。如果是,请运行这些功能。 如果他们不这样做,请单独留下页面。
然后,查看所有主题 如果template.php有钩子, 根据他们的功能名称,将会 修改页面。如果他们这样做,运行 功能。如果他们不这样做,请离开 单独的页面。
最后,查看tpl.php文件并使用这些文件显示页面。如果没有正确文件名的tpl.php文件,则使用node.tpl.php加载它
所有http://drupal.org/node/173880
的摘要如果你在template.php中没有看起来像是修改页面的函数,并且你没有与你正在寻找的节点匹配的tpl.php文件,那就意味着所有的页面都是使用默认模板。
(这可能就是为什么你的前任设置了他所做的奇怪结构。使用这样的函数是一种有点hacky方式来做Drupal可以通过主题函数自动完成的事情)
所以:
继续制作tpl.php文件。如果您的内容类型是博客节点或其他内容,请将其命名为node-blog.tpl.php。您现在可以只复制现有的tpl.php文件。然后,在template.php中创建一个预处理函数以与其一起使用。
(您需要重建Drupal的主题注册表以识别更改 - 您已经安装了Devel模块,因此它应该很容易。您站点上的Visiting / admin / build / modules也可以正常工作。)
然后,访问http://drupal.org/node/223430和http://drupal.org/node/337022以获取一些快速解释和代码段,以便您将数据作为变量传递,然后模板可以在您的页面上呈现
最后一次编辑:
这个功能是否可以构建一个博客帖子列表,并以摘要形式(例如待定帖子列表)显示信息?
我问,因为如果是这样,Views模块可能会为您完成所有这项工作。除非函数abc()中的数据处理真的,真的,花哨,这似乎只是为Views
构建的那种东西。
答案 2 :(得分:1)
为了澄清我的评论,它看起来应该是这样的:
function getData(){
$sql='my sql query';
results =db_query($sql);
$return_string = '' ;
while ($data = db_fetch_array($results)) {
//Loop through data and save to $db_data
$return_string .= $db_data;
}
return $return_string;
}
听起来你正好在page.tpl.php中调用这个函数;请注意,您可以通过有条件地调用它来显示特定值$ node-&gt; nid来显示它:
<?php if ($node->nid == xxx || $node->nid == yyy) print getData() ;?>
如果您正在使用CCK并仅针对特定内容类型显示您的功能结果,Contemplate是一个很好的模块,尤其是。对于开始Drupalers,这使得其中一些更容易。
答案 3 :(得分:0)
虽然template.php用于覆盖各种主题函数,但它也可以用来简单地存储模板上调用的函数(你也可以强制template.php在自定义模块中可用,具体取决于网站的hacky)由原始开发人员完成。所以只是因为函数在template.php中并不会自动假设它是一个主题覆盖(如果你可以提供它的实际名称,它将有助于确定它是否是)。
将代码从函数中删除但将其保留在template.php中的原因导致每个页面上的输出是因为template.php包含在每个页面中。从理论上讲,你可以在template.php中添加不仅仅是函数。在一个大型网站上,我在其中一个开发人员将这些功能分解为几个较小的文件,因此template.php只有2或3个函数,3或4个包含()。
了解函数的实际名称确实有助于确定这是自定义函数还是主题覆盖。
答案 4 :(得分:0)
回答你提出的一些问题:
上一个功能是这样做的:
function abc($node,$submitted,$node_url) {
echo $node->taxonomy['color'];
$a = explode(",",$submitted);
$b = explode("-",$a[1]);
// THIS IS THE DESCRIPTION
if(strlen($node->content['body']['#value'])>180)
{
$c = str_split($node->content['body']['#value'],180);
$d = $c[0]."...";
}
else{
$d = $node->content['body']['#value'];
}
$multiple = $node->field_mul_event[0]['view'];
$eventcode = $node->field_event_code[0]['value'];
$strdata="";
$strdata.="specific markup to output here";
return $strdata;
}
此功能只需提取开始和结束日期以及说明
我的代码中的sql字符串是:
select DISTINCT node.nid AS nid, node.title AS node_title,
content_type_blog.field_date_from_value AS node_data_field_date_from_field_date_from_value,
DATE_FORMAT(content_type_blog.field_date_from_value, '%%d/%%m/%%Y') AS dateFrom,
content_type_blog.field_date_from_value2 AS node_data_field_date_from_field_date_from_value2,
content_type_blog.nid AS node_data_field_date_from_nid,
field_mul_event_value AS multiEvent,
field_event_code_value AS eventCode,
node.type AS node_type,
content_type_blog.field_event_excerpt_value AS node_data_field_date_from_field_event_excerpt_value,
image_attach.iid AS image_attach_iid,
node_images.filepath AS imagePath,
color AS catColour
FROM node
node LEFT JOIN content_type_blog content_type_blog ON node.vid = content_type_blog.vid
LEFT JOIN image_attach image_attach ON node.nid = image_attach.nid
LEFT JOIN node_images node_images ON node.nid = node_images.nid
LEFT JOIN term_node term_node ON node.nid = term_node.nid
LEFT JOIN term_data term_data ON term_node.tid = term_data.tid
WHERE node.type LIKE 'blog' AND content_type_blog.field_date_from_value >= DATE(NOW()) AND content_type_blog.field_date_from_value2 >= DATE(NOW())
ORDER BY content_type_blog.field_date_from_value ASC
我相信你可以知道,这个sql抓取所有相同的数据(和一些额外的信息),除了比今天更早的数据,然后按日期顺序命令。
我查看了主题文件夹,并且有两个tpl.php文件,其中包含相同的代码:
<?php print $fields['title']->content; ?>
<?php print $fields['introduction']->content; ?>
我无法在sites / all / modules中看到任何自定义模块。这是那里的列表(但它们对我来说似乎都是固有的模块):
请原谅我的无知 - 但随着我的进展,我正在学习drupal。如果你知道我的意思,通常更多的是wordpress gal。不习惯节点/分类/ drupal系统等,这是我缺乏知识的基础借口。
我需要找到这个功能并确定它的功能 - gah !!!
谢谢大家!
答案 5 :(得分:0)
好看了一下使用主题开发者:
父母:theme_taxonomy_term_page&lt; page.tpl.php中 模板叫: node.tpl.php 使用的文件: 模块/节点/ node.tpl.php 候选模板文件: node-blog.tpl.php&lt; node.tpl.php 预处理功能: template_preprocess + template_preprocess_node + content_preprocess_node + nodereference_preprocess_node + views_preprocess_node 持续时间:6.84毫秒
在这里查看 modules / node / node.tpl.php ,找到对abc函数的引用
<?php print abc($node,$submitted,$node_url); ?>
找不到node-blog.tpl.php并且找不到对函数的任何引用template_preprocess + template_preprocess_node + content_preprocess_node + nodereference_preprocess_node + views_preprocess_node
难住了。
答案 6 :(得分:0)
一个很好的开始,看看主题钩子和模板文件发生了什么是devel module。启用它并进入网站并启用“主题开发人员”模块会在页面的左下角为您提供一些小工具,您可以在其中选中一个框,然后单击页面上的任何元素 - 它将会向您展示它正在执行什么,为什么以及它可以执行什么。
可能是一个开始。