Release Notes部分是如何构造的< / span >
在开始编辑模板之前,了解已完成的部分是如何工作的将会很有帮助。默认情况下,在Pages数据库中,您将看到一个记录列表(使用< em>清单< / em >模板),单击该记录,该记录加载一个新页面来显示它(使用< em>显示< / em >模板)。然而,在我们的Release Notes数据库中,没有页面重新加载——记录是通过AJAX动态加载的。
这是通过混合两个< em>清单< / em >和< em>显示< / em >模板。页的包装器和左边的版本列表是使用< em>清单< / em >模板。但是,当单击并动态加载记录时,页面的该部分将使用< em>显示< / em >模板:
现在结构已经清晰了,终于可以开始编辑模板了!
下面和下一步讨论的每个模板都包含一个diff报告的链接,以便您可以轻松地将我们所做的更改与默认模板进行比较。
清单头-< em>categoryHeader< / em >模板< / span ><跨style="font-size:18px;">(见diff)< / >
我们要处理的第一个模板是category header。这显示了类别的标题(在我们的例子中,它实际上是整个部分的标题,因为用户在使用数据库时不会离开这个页面)。的< em>categoryHeader< / em >模板处理标题、跟随按钮、< em>添加记录< / em >按钮等等。
下面是这个模板位的最终代码,我将在下面解释它。
{{如果! \ IPS \请求::我()——> advancedSearchForm}}< / span ><跨类="tag">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsType_center ipsSpacer_bottom ipsSpacer_top”< / span ><跨类="tag">>< / span ><跨类="pln">< h1< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsType_veryLarge ipsType_reset”< / span ><跨类="tag">>< / span ><跨类="pln">{$分类- > _title}< / span ><跨类="tag">< / h1 >< / span ><跨类="pln">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">"ipsType_richText ipsType_large ipsType_light ipsSpacer_bottom"< / span ><跨类="tag">>< / span ><跨类="pln">{$分类- > _description |生}< / span ><跨类="tag">< / div >< / span ><跨类="pln">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsResponsive_noFloat ipsResponsive_hidePhone”< / span ><跨类="tag">>< / span ><跨类="pln">{template="follow" app="core" group="global" params="'cms','categories'。$category->database_id, $category->_id, \IPS\cms\Records::containerFollowerCount($category)"}< / span ><跨类="tag">< / div >< / span ><跨类="pln">< / div >< / span ><跨类="pln">{{endif}} {{if $category->hasChildren() AND !收取(\ IPS \要求::我()——> advancedSearchForm)}}< / span ><跨类="tag">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsBox ipsSpacer_bottom”< / span ><跨类="tag">>< / span ><跨类="pln">< h2< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsType_sectionTitle ipsType_reset”< / span ><跨类="tag">>< / span ><跨类="pln">{lang = " content_subcategories_title "}< / span ><跨类="tag">< / h2 >< / span ><跨类="pln">< ol< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsDataList”< / span ><跨类="tag">>< / span ><跨类="pln">{{foreach $category->children() as $cat}} {template="categoryRow" group="category_index" location="database" app="cms" params="$cat"} {{endforeach}}< / span ><跨类="tag">< / ol >< / span ><跨类="pln">< / div >< / span ><跨类="pln">{{endif}} {{if $category->can('add')}} {{if !\ IPS \要求::我()——> isAjax()和!isset(\IPS\Request::i()->advancedSearchForm) AND $category->show_records}}< / span ><跨类="tag">< ul< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">ipsToolList ipsToolList_horizontal ipsClearfix ipsSpacer_both ipsResponsive_hidePhone< / span ><跨类="tag">>< / span ><跨类="pln"><李< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsToolList_primaryAction”< / span ><跨类="tag">>< / span ><跨类="pln"><一个< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">ipsButton ipsButton_medium ipsButton_important ipsButton_fullWidth< / span ><跨类="pln">href< / span ><跨类="pun">=< / span ><跨类="atv">“{类别- >< / span ><跨类="pln">}">{lang="cms_add_new_record_button" sprintf="\IPS\cms\数据库::load($category->database_id)->recordWord(1)"} "}< / span ><跨类="tag">< / >< / span ><跨类="pln">李< / >< / span ><跨类="pln">< / ul >< / span ><跨类="pln">{{endif}} {{endif}} {{if count($activeFilters) AND !isset(\IPS\Request::i()->advancedSearchForm)}} {template="filterMessage" app="cms" location="database" group="release_notes" params="$activeFilters, $category"} {{endif}}< / span >
这个模板与默认模板非常相似。关键的改变是:
清单表-< em>categoryTable< / em >模板< / span ><跨style="font-size:18px;">(见diff)< / >
的< em>categoryTable< / em >模板是列表视图的“肉”;它生成记录行显示的表。这个模板在默认模板的基础上进行了大量修改,部分原因是删除了大量未使用的代码。
注意:模板通常包含大量代码,当数据库启用某个选项时使用这些代码。此代码被包装在一个逻辑检查中,因此只有在启用该选项时才会显示它。当我确定不需要这些代码显示的特性时,我倾向于删除这些未使用的部分;它使模板更简洁,更容易阅读。
下面是这个模板位的最终代码:
< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsAreaBackground ipsPad_half”< / span ><跨类="pln">data-baseurl< / span ><跨类="pun">=< / span ><跨类="atv">‘{$表- >< / span ><跨类="pln">baseUrl}‘data-resort ={表- > resortKey} core.global.core数据控制器=。表{{如果美元表- > canModerate ()}}, core.front.core.moderation {{endif}} " >< / span ><跨类="tag">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsAreaBackground_reset ipsColumns ipsColumns_collapsePhone”< / span ><跨类="pln">数据控制器< / span ><跨类="pun">=< / span ><跨类="atv">“pages.front.releaseNotes.main”< / span ><跨类="tag">>< / span ><跨类="pln">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">'ipsColumn ipsColumn_wide ipsAreaBackground creleaseccolumn '< / span ><跨类="pln">data-role< / span ><跨类="pun">=< / span ><跨类="atv">“发布”< / span ><跨类="tag">>< / span ><跨类="pln">{{如果!count($行)}}< / span ><跨类="tag">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsPad”< / span ><跨类="tag">>< / span ><跨类="pln">{lang="cms_no_records_to_show" sprintf="\IPS\cms\Databases::load(\IPS\cms\Databases\Dispatcher::i()->databaseId)->recordWord()"}< / span ><跨类="tag">< / div >< / span ><跨类="pln">{{其他}}< / span ><跨类="tag">< ol< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">'ipsDataList ipsDataList_zebra ipclear ccmslist {{foreach $table-> . txt< / span ><跨类="pln">$class}}{$class} {{endforeach}}' id='elTable_{$table->uniqueId}' data-role="tableRows"> {template="$table->rowsTemplate[1]" params="$table, $headers, $rows" object="$table->rowsTemplate[0]"}< / span ><跨类="tag">< / ol >< / span ><跨类="pln">{{endif}} {{if $table->pages > 1}}< / span ><跨类="tag">< div< / span ><跨类="pln">data-role< / span ><跨类="pun">=< / span ><跨类="atv">“tablePagination”< / span ><跨类="tag">>< / span ><跨类="pln">{template="pagination" group="global" app="core" location="global" params="$table->baseUrl, $table->pages, $table->page, $table->limit"}< / span ><跨类="tag">< / div >< / span ><跨类="pln">{{endif}}< / span ><跨类="tag">< / div >< / span ><跨类="pln">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsColumn ipsColumn_fluid”< / span ><跨类="tag">>< / span ><跨类="pln">< div< / span ><跨类="pln">data-role< / span ><跨类="pun">=< / span ><跨类="atv">“releaseInfo”< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsPad_double”< / span ><跨类="tag">> < / div >< / span ><跨类="pln">< / div >< / span ><跨类="pln">< / div >< / span ><跨类="pln">< / div >< / span >
以下是关键的变化:
清单行-< em>recordRow< / em >模板< / span ><跨style="font-size:18px;">(见diff)< / >
该模板生成清单表的每一行。这是我们要做一些特殊工作的第一个模板,所以我将在下面介绍这些部分。以下是最终代码:
}} {{$ipost = ($table AND method_exists($table, 'container') AND $table->container() !== NULL) ?}} {$ipost = ($table AND method_exists($table, 'container') AND $table->container() !$table->container()->contentPostedIn(null, $rowIds): array();}} {{foreach $rows as $row}} {$idField = $row::$databaseColumnId;< / span ><跨类="tag"><李< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“cCmsRecord_row{{如果美元行- >< / span ><跨类="pln">隐藏()}}ipsModerated {{endif}}“data-rowID =‘{$行- > $ idField} >< / span ><跨类="tag"><一个< / span ><跨类="pln">href< / span ><跨类="pun">=< / span ><跨类="atv">{$ row - >< / span ><跨类="pln">url()}' class='cRelease' data-releaseID='{$row->$idField}' {{if $row->fieldValues()['field_163']}}data-currentRelease{{endif}}> {$row->customFieldDisplayByKey('security-release', 'listing')|raw}< / span ><跨类="tag">< h3< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsType_sectionHead ipsType_break”< / span ><跨类="tag">>< / span ><跨类="pln">{{如果美元行- > _title}}{$行- > _title}{{其他}}< / span ><跨类="tag">< em< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsType_light”< / span ><跨类="tag">>< / span ><跨类="pln">{lang = " content_deleted "}< / span ><跨类="tag">< / em >< / span ><跨类="pln">{{endif}} {$row->customFieldDisplayByKey('current-release', 'listing')|raw} {$row->customFieldDisplayByKey('beta-release', 'listing')|raw}< / span ><跨类="tag">< / h3 >< / span ><跨类="pln">{{如果美元行- > isFutureDate() | | $行- >映射(固定的)| | $行- >映射(特色)| | $行- >隐藏()= = = 1 | | $行- >隐藏()= = = 1}}< / span ><跨类="tag">< span >< / span ><跨类="pln">{{如果美元行- > isFutureDate ()}}< / span ><跨类="tag"><跨< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">"ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning"< / span ><跨类="pln">data-ipsTooltip< / span ><跨类="pln">标题< / span ><跨类="pun">=< / span ><跨类="atv">{$ row - >< / span ><跨类="pln">futureDateBlurb ()} " >< / span ><跨类="tag"><我< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“fa fa-clock-o”< / span ><跨类="tag">> < / i > < / span >< / span ><跨类="pln">{{elseif $row->hidden() === -1}}< / span ><跨类="tag"><跨< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">"ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning"< / span ><跨类="pln">data-ipsTooltip< / span ><跨类="pln">标题< / span ><跨类="pun">=< / span ><跨类="atv">{$ row - >< / span ><跨类="pln">hiddenBlurb ()} " >< / span ><跨类="tag"><我< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“fa fa-eye-slash”< / span ><跨类="tag">> < / i > < / span >< / span ><跨类="pln">{{elseif $row->hidden() === 1}}< / span ><跨类="tag"><跨< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">"ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_warning"< / span ><跨类="pln">data-ipsTooltip< / span ><跨类="pln">标题< / span ><跨类="pun">=< / span ><跨类="atv">“{lang = pending_approval“}”< / span ><跨类="tag">> <我< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“fa fa-warning”< / span ><跨类="tag">> < / i > < / span >< / span ><跨类="pln">{{endif}}{{如果行- >映射(固定)}}< / span ><跨类="tag"><跨< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_positive< / span ><跨类="pln">data-ipsTooltip< / span ><跨类="pln">标题< / span ><跨类="pun">=< / span ><跨类="atv">“{lang =“固定”}”< / span ><跨类="tag">> <我< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“fa fa-thumb-tack”< / span ><跨类="tag">> < / i > < / span >< / span ><跨类="pln">{{endif}}{{如果行- >映射(中)}}< / span ><跨类="tag"><跨< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">ipsBadge ipsBadge_icon ipsBadge_small ipsBadge_positive< / span ><跨类="pln">data-ipsTooltip< / span ><跨类="pln">标题< / span ><跨类="pun">=< / span ><跨类="atv">“{lang =“特色“}”< / span ><跨类="tag">> <我< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“fa fa-star”< / span ><跨类="tag">> < / i > < / span >< / span ><跨类="pln">{{endif}}< / span ><跨类="tag">< / span >< / span ><跨类="pln">{{endif}} {{if count($row->customFieldsForDisplay('listing'))}}< / span ><跨类="tag">< div< / span ><跨类="pln">类< / span ><跨类="pun">=< / span ><跨类="atv">“ipsDataItem_meta”< / span ><跨类="tag">>< / span ><跨类="pln">{{foreach $row->customFieldsForDisplay('listing') as $ fielddid => $fieldValue}} {{if $fieldValue && $ fielddid != 'current-release' && $ fielddid != 'beta-release' && $ fielddid != 'security-release'}} {$fieldValue|raw} {{endif}} {{endforeach}}< / span ><跨类="tag">< / div >< / span ><跨类="pln">{{endif}}< / span ><跨类="tag">< / >< / span ><跨类="pln">李< / >< / span ><跨类="pln">{{endforeach}}< / span >
与前面的模板一样,大量未使用的代码被删除了。
前几行也是默认设置。接着,我们进入主循环,它遍历每一行并为每一行生成HTML。
我想强调的第一部分是<跨style="font-family:courier new,courier,monospace;"><一>< / span >元素。注意,我们已经应用了一个自定义类名,用于样式化。我们还添加了data-releaseID属性,其值是记录的ID。这很重要,因为稍后当用户单击清单中的这条记录时,我们将使用它来加载正确的记录。
访问原始字段值< / span >
在同一行,你会看到:
{{如果美元行- > fieldValues()内[' field_163 ']}} data-currentRelease {{endif}}< / span >
现在的情况是我们在打电话<跨style="font-family:courier new,courier,monospace;">行- > fieldValues()内< / span >(返回一行的所有字段值的数组),并使用它来确定field_163是否为真。如果是,则使用data属性将其标记为当前版本。您可以正确地假设163字段是我们设置的当前版本字段。不幸的是,当使用时,我们必须通过ID而不是键来引用它<跨style="font-family:courier new,courier,monospace;">fieldValues(内)< / span >方法,这会使检查稍微复杂化。
注意:在您自己的数据库中,当前版本字段将有一个不同的ID。用设置中的字段ID替换field_163。
访问格式化字段输出< / span >
在这个模板中,你会看到这样的调用:
{$行- > customFieldDisplayByKey(“安全更新”、“清单”)|生}
这将返回一个自定义字段的输出< em>security_release< / em >在本例中切换)。它从我们为字段设置的格式选项返回生成的HTML。这就是自定义格式化器如此有用的原因——我们可以在字段编辑屏幕上整洁地管理字段的输出,并使用上面的简单标记将其插入到模板中。注意,我们通过了< em>清单< / em >值的第二个参数。这表示我们想要清单格式(如果您还记得,您可以为< em>清单< / em >和< em>显示< / em >模板)。