打开你的文本编辑器,新建一个文件。在这里,我们将使用HTML 和PHP。首先,先输入一些基本的东西,以供将来定义CSS时使用。
<div class="content agency">
</div>
<div class="clear-block clear"></div>
它的意思是说,“下面的是这个节点的内容,节点类型为'agency'”。这里我选择使用了机器可读的节点类型作为内容标识,你也可以使用自己的标识。"content"是Drupal的标准用法,所以你需要保留它。第2行仅仅是一个结束标签。第3行也不是必需的,但是由于我们的节点中包含了图片,图片的大小可能会有所不同,加上这一行,能让浏览器返回“起点处”,从而保持统一的外观。
那么,现在我假设你想输出一些实际的内容?
节点中包含了一个图片,这里我们用的是使用了ImageCache模块的CCK "Image"字段。我们想把图片放在左上方。实际上,如果把公司名(标题)放在图片上方的话,效果可能会好一些,至于标题和图片的位置问题,我们现在先不管它,首先要做的是将它们显示出来。我们将这些东西插入到第一个<div>标签中。
ImageCache模块提供了一个非常方便的主题函数,让我们来使用它。
[顺便说一句,'echo'函数比'print'函数稍微快一点,所以我使用'echo'。不过大多数主题制作者都使用'print'。两者都能工作。
]
<?php echo theme('imagecache', 'thumbnail', $node->field_logo[0]['filepath'], $node->title, $node->title, array('align' => 'left', 'hspace' => '10')); ?>
在这个函数中,首先使用"thumbnail"(可以改为你自己要用的)来设置图片的大小。对于数据字段("$node->field_logo[0]['filepath']"),我将在下面作出解释。接下来的两个"$node->title"参数,它是告诉函数,对于"alt" 和"title"属性,在这里都使用公司名称。最后,我们使用了一个数组,它告诉ImageCache向IMG标签中添加属性'align="left"' 和'hspace="10"'。
好了,我们把图片插进去了,现在轮到标题了。在Drupal中,最标准的做法是使用<h2>标签。这个取决于你的习惯,不过在这里我将遵循Drupal标准。整个节点对象在主题中都是可用的,按照Drupal标准的,它叫作"$node"。在节点对象内部的标题(在这种情况下,就是公司名称),它的叫法就有点奇怪了,叫做 "title",而不是“company_name”。因此我们可以使用"$node->title"来引用它。
<h2><?php echo l($node->title, 'node/'. $node->nid, array('title' => t('View agency')));?></h2>
另一个标准的Drupal做法是,在标题上加一个指向节点本身的链接,这样你就可以进入节点页面,如果有权限的话,可对其进行编辑。所以我在这里使用l()函数。关于这个函数的更多信息,可参看这里。
在我的例子中,我使用表格(table)来对数据进行格式化。你也可以这样做,或者你也可以使用<div>+CSS。有些主题制作者就喜欢使用后者。你可以自由的选用你喜欢的技术。但一定要小心,不要与你的主题冲突了。
在我的例子中,我使用了CCK_Address模块,由于它与其它的CCK字段有点区别,所以我将讲解一下它的字段是怎么命名的。地址模块允许使用多个地址;多个地址构成一个名为"field_address"的数组,所以第一个地址是0,第2个地址是1,以此类推。这个模块还提供了几个子字段,它们的标签不需要与编辑页面的保持一致。比如,显示的"Address"字段,在内部为"street1";"Address continued"在内部为"street2";而"Apt/suite number"则简记为"apt."
我没有能够为这些字段使用"content_format"函数来格式化它们的内容。不知这是好是坏,但是它能工作。而普通的CCK字段有一个安全的"view"元素可用。
<tr><th>Address</th><td>
<?php
echo $node->field_address[0]['street1'];
if ($node->field_address[0]['apt']) { echo '; '. $node->field_address[0]['apt']; }
if ($node->field_address[0]['street2']) { echo '<br/>'. $node->field_address[0]['street2']; }
echo '<br/>'. $node->field_address[0]['city'] .', '. $node->field_address[0]['state'] .' '. $node->field_address[0]['zip'];
if ($node->field_address[0]['country'] != 'US') { echo '<br/><big>'. $node->field_address[0]['country'] .'</big>'; }
?>
</td></tr>
注意,我这里加了一点逻辑,从而将城市,州,和邮政编码连在一起(采用美国的格式)。由于我就在美国,所以也没有显示"US",如果加上这个的话,这里的邮递员会觉得别扭的。
现在,除了"body"字段(也就是这里的"description")以外,到目前为止,所遇到的所有字段的处理方式都是一样的。如果你参考一下你的“管理字段集”("manage fields")页面的字段名称,现在仅有几点需要你了解。
和前面的"address"一样,CCK所有字段可以是单独的,也可以是多个的,所以需要使用数足来管理它们,数组名就为“管理字段集”页面的字段名。例如,我们把电话号码定义为"field_agency_telephone",这个和前面的一样,第一个元素为field_agency_telephone[0],第2个元素为field_agency_telephone[1],以此类推。在我们这种情况下,不需要多个电话号码,如果需要的话,使用一个简单的"foreach"循环就可以做到了。
CCK提供了一个内容格式化工具(content formatter),但是你用不到它。每一个字段数组,都有一个‘view’,这个就是内容格式化工具生成的,但它已经为你做好了。这是展示数据的安全方式。而对于电子邮件地址和超链接等字段内容,CCK已经对其进行了正确的格式化处理。
让我们归者一下,引用一个字段的最好的方式就是"$field_name[0]['view'],"其中field_name可从“管理字段集”页面找到。
<tr><th>Phone</th><td><?php echo $node->field_phone[0]['view'];?></td></tr>
<tr><th>Email</th><td><?php echo $node->field_email[0]['view'];?></td></tr>
<tr><th>Web site</th><td><?php echo $node->field_website[0]['view'];?></td></tr>
那么,现在基本上就快完工了;现在就剩下"description"(或者body)字段需要考虑了。这个与前面所讲的不一样,所以你必须要小心一点。这个字段是这样引用的,"$node->content['body']['#value']",我看到一些人在帖子中建议,"$node->description"也应该可以工作,但是现在还不能。
那么,让我们将整个例子正合到一起,希望我的讲解还算清晰明了:
<div class="content agency">
<?php echo theme('imagecache', 'thumbnail', $node->field_logo[0]['filepath'], $node->title, $node->title, array('align' => 'left', 'hspace' => '10')); ?>
<h2><big><?php echo l($node->title, 'node/'. $node->nid, array('title' => t('View agency')));?></big></h2><br/>
<table border="2" cellpadding="5">
<tr><th>Address</th><td>
<?php
echo $node->field_address[0]['street1'];
if ($node->field_address[0]['apt']) { echo '; '. $node->field_address[0]['apt']; }
if ($node->field_address[0]['street2']) { echo '<br/>'. $node->field_address[0]['street2']; }
echo '<br/>'. $node->field_address[0]['city'] .', '. $node->field_address[0]['state'] .' '. $node->field_address[0]['zip'];
if ($node->field_address[0]['country'] != 'US') { echo '<br/><big>'. $node->field_address[0]['country'] .'</big>'; }
?>
</td></tr>
<tr><th>Phone</th><td><?php echo $node->field_phone[0]['view'];?></td></tr>
<tr><th>Email</th><td><?php echo $node->field_email[0]['view'];?></td></tr>
<tr><th>Web site</th><td><?php echo $node->field_website[0]['view'];?></td></tr>
</table>
<?php
if ($node->content['body']['#value']) {
echo '<p><big>'. $node->content['body']['#value'] .'</big></p>';
}
?>
</div>
<div class="clear-block clear"></div>
While I initially developed this on the Bluemarine theme, it worked without change on the
这个模板文件,我最初是在Bluemarine主题下面开发的,当我把它放在Garland主题下时,只需要在我的CSS中加入".agency table {width: auto;}"就可以了。其它都不用修改。这是由于Garland主题忽略了我的"width"属性,并将其强制为100%的缘故。
最后…
现在将你的工作保存,并检查它是否正常工作。
将文件保存到你主题的文件夹下,取名为"node-content_type.tpl.php",其中content_type是你在第一步中给节点类型起的内部名字。
展示一列节点
站点已经安装了Views模块,这样我就可以使用这个模块来选择资源了,尽管我觉得这样运行效率低一些。
由于所有字段在主题中都列出来了,那么我在Views中需要做些什么呢?对于"teaser view",我发现所有要做的就是选择节点中的字段,比如标题等等,然后你就得到了想要的节点。你可能还想排个序,但是这已经不是本文讨论的范围了。