RocketDirectory AppTheme
Overview
RocketDirectory is the full-featured directory/catalogue module system in Rocket. It is the basis for RocketBlog, RocketNews, RocketEvents, and RocketProducts — all of which share the same AppTheme structure and token inheritance.
A RocketDirectory AppTheme controls: list and detail views, the admin article/category/property editors, category menus, tag/filter panels, satellite templates, and module theme settings.
Template Header
All RocketDirectory templates (and derived systems) use:
@inherits RocketDirectoryAPI.Components.RocketDirectoryAPITokens<Simplisity.SimplisityRazor>
@using DNNrocketAPI.Components;
@using RocketDirectoryAPI.Components;
@AssignDataModel(Model)
<!--inject-->
The @AssignDataModel(Model) call populates all pre-defined model objects automatically. The two @using statements are required for the types used in template code blocks.
Pre-Defined Model Objects
After @AssignDataModel(Model), the following objects are directly available in the template:
| Object | Type | Description |
|---|---|---|
articleData |
ArticleLimpet |
A single article (populated when viewing a detail page or editing an article). null in list context. |
articleDataList |
ArticleLimpetList |
The paged article result set. Call .GetArticleList() to get the enumerable list of ArticleLimpet. |
categoryData |
CategoryLimpet |
The currently active category filter. |
categoryDataList |
CategoryLimpetList |
The full category tree for the system. |
propertyData |
PropertyLimpet |
A single property/tag record. |
propertyDataList |
PropertyLimpetList |
The full property/tag list. |
moduleData |
ModuleContentLimpet |
Module settings and configuration. Use .GetSetting("key") or .GetSettingBool("key"). |
moduleSettings |
ModuleContentLimpet |
Alias for moduleData (legacy compatibility). |
portalData |
PortalLimpet |
Portal-level data (name, culture, paths). |
catalogSettings |
CatalogSettingsLimpet |
System-wide catalogue configuration (page sizes, default sorting, etc.). |
sessionParams |
SessionParams |
Current request session data, culture, page, paging. |
userParams |
UserParams |
Current logged-in user details. |
appTheme |
AppThemeLimpet |
The current view AppTheme. |
appThemeDefault |
AppThemeLimpet |
The fallback/default AppTheme. |
appThemeSystem |
AppThemeSystemLimpet |
The system-level shared template object. |
appThemeDirectory |
AppThemeSystemLimpet |
The directory-system shared templates (used for [INJECT:appthemedirectory,...]). |
appThemeDirectoryDefault |
AppThemeLimpet |
The default directory AppTheme. |
info |
SimplisityInfo |
Raw XML data node for the current articleData record. |
infoempty |
SimplisityInfo |
Empty SimplisityInfo node used in add/review forms. |
moduleDataInfo |
SimplisityInfo |
Raw XML info for the module record. |
AppTheme Object Keys (for [INJECT])
| Key | Object |
|---|---|
apptheme |
appTheme (current view theme) |
appthemedefault |
appThemeDefault |
appthemesystem |
appThemeSystem (system-level shared templates) |
appthemedirectory |
appThemeDirectory (directory shared templates) |
appthemedirectorydefault |
appThemeDirectoryDefault |
appthemeview |
Resolved view theme (used in some shared templates) |
appthemeshared |
Portal-level shared templates |
Standard Template Set
A typical RocketDirectory AppTheme contains:
| Template | Purpose |
|---|---|
View.cshtml |
Main public view: switches between list and detail based on URL params |
ListView.cshtml |
Alternative list-only view |
ArticleList.cshtml |
Renders the paged article list (injected by View.cshtml) |
ArticleDetail.cshtml |
Renders a single article detail page (injected by View.cshtml) |
ArticleSat.cshtml |
Satellite template — displays data without loading it (see cmd satellite) |
Categories.cshtml |
Category sidebar/menu template |
Tags.cshtml |
Tag filter panel |
Filters.cshtml |
Property filter panel |
AdminDetail.cshtml |
Admin single-article edit form |
AdminList.cshtml |
Admin paged article list |
AdminHeader.cshtml |
Admin panel header template (placeholder; usually empty) |
AdminExtra.cshtml |
Extra admin fields template (optional extension) |
ThemeSettings.cshtml |
Per-module display settings panel |
LayoutText.cshtml |
Text/content block used within article list/detail cards |
Rss.cshtml |
RSS feed template |
View Template Pattern
View.cshtml is the entry point. It displays either a detail article or a list depending on whether articleData is populated (i.e. whether the URL contains an article id param):
@inherits RocketDirectoryAPI.Components.RocketDirectoryAPITokens<Simplisity.SimplisityRazor>
@using DNNrocketAPI.Components;
@using RocketDirectoryAPI.Components;
@AssignDataModel(Model)
@AddProcessDataResx(appTheme, true)
<!--inject-->
@{
var hasSidebar = moduleData.GetSettingBool("showcategories")
|| moduleData.GetSettingBool("showtags")
|| moduleData.GetSettingBool("showfilters");
var mainCol = hasSidebar ? "w3-col l9 m8 s12" : "w3-col l12";
}
<div class="w3-content" style="max-width:1400px;">
<div class="w3-row-padding">
<div class="@mainCol">
@if (articleData != null)
{
<text>[INJECT: apptheme, ArticleDetail.cshtml]</text>
}
else
{
<text>[INJECT: apptheme, ArticleList.cshtml]</text>
}
</div>
@if (hasSidebar)
{
<div class="w3-col l3 m4 s12">
@if (moduleData.GetSettingBool("showcategories"))
{
[INJECT: apptheme, Categories.cshtml]
}
@if (moduleData.GetSettingBool("showtags"))
{
[INJECT: apptheme, Tags.cshtml]
}
@if (moduleData.GetSettingBool("showfilters"))
{
[INJECT: apptheme, Filters.cshtml]
}
</div>
}
</div>
</div>
Article List Pattern
@{
var articleList = articleDataList.GetArticleList();
var width = moduleData.GetSettingInt("width");
}
@foreach (var article in articleList)
{
var info = article.Info;
var articleImage = article.GetImage(0);
var detailUrl = DetailUrl(moduleData.DetailPageTabId(), article, categoryData,
new string[] { "page", sessionParams.Page.ToString() });
<div class="w3-col l4 m6 s12 w3-margin-bottom">
<div class="w3-card w3-white w3-round-large">
<a href="@detailUrl">
<img src="@ImageUrl(articleImage.RelPath, width, 200)" alt="@article.Name" />
</a>
[INJECT:appthemeview, LayoutText.cshtml]
</div>
</div>
}
<div class="w3-center">
[INJECT:appthemedirectorydefault, articlePaging.cshtml]
</div>
Key points:
articleDataList.GetArticleList()returnsIEnumerable<ArticleLimpet>.DetailUrl(tabId, article, categoryData, extras)builds the SEO-friendly detail URL.[INJECT:appthemedirectorydefault,articlePaging.cshtml]renders the shared pagination control.[INJECT:appthemedirectorydefault,SearchBanner.cshtml]adds the search/sort bar above the list.
Admin Templates
AdminList.cshtml
Renders the paged admin list of articles:
@inherits RocketDirectoryAPI.Components.RocketDirectoryAPITokens<Simplisity.SimplisityRazor>
@using DNNrocketAPI.Components;
@using RocketDirectoryAPI.Components;
@AssignDataModel(Model)
@AddProcessDataResx(appTheme, true)
<!--inject-->
[INJECT:appthemedirectory,AdminSearch.cshtml]
<table class="w3-table w3-bordered w3-hoverable">
@foreach (ArticleLimpet article in articleDataList.GetArticleList())
{
<tr class="simplisity_click"
s-cmd="articleadmin_editarticle"
s-fields='{"articleid":"@article.ArticleId","track":"true"}'
style="cursor:pointer;">
<td><img src="@ImageUrl(article.GetImage(0).RelPath, 48, 48)" class="w3-round" /></td>
<td><b>@article.Name</b></td>
</tr>
}
</table>
@RenderTemplate("AdminPaging.cshtml", appThemeDirectory, Model, true)
AdminDetail.cshtml
The article edit form. Uses [INJECT:appthemedirectory,...] calls to compose the form from shared directory-level blocks:
@inherits RocketDirectoryAPI.Components.RocketDirectoryAPITokens<Simplisity.SimplisityRazor>
@using DNNrocketAPI.Components;
@using RocketDirectoryAPI.Components;
@AssignDataModel(Model)
@AddProcessDataResx(appTheme, true)
<!--inject-->
<div id="articleeditcontent" class="w3-card w3-padding w3-white">
[INJECT:appthemedirectory,editbuttonbar.cshtml]
<div class="w3-row">
<div class="w3-twothird w3-padding-small">
[INJECT:appthemesystem,AdminGeneralBlock.cshtml]
[INJECT:appthemedirectory,ArticleModelsBlock.cshtml]
</div>
<div class="w3-third w3-padding-small">
[INJECT:appthemedirectory,ArticleCategoryListBlock.cshtml]
[INJECT:appthemedirectory,ArticlePropertyListBlock.cshtml]
[INJECT:appthemedirectory,ArticleimagesBlock.cshtml]
[INJECT:appthemedirectory,ArticleDocumentsBlock.cshtml]
[INJECT:appthemedirectory,ArticleLinksBlock.cshtml]
</div>
</div>
</div>
Unlike RocketContent, the RocketDirectory admin detail form is mostly composed from shared
appthemedirectoryblocks. Custom fields specific to your theme go inAdminExtra.cshtml, which is injected byArticleModelsBlock.cshtml.
ThemeSettings.cshtml
Module display settings. Settings are read from moduleData.GetSetting("key") and saved under the genxml/settings/ xPath:
@{
var moduleData = (ModuleContentLimpet)Model.GetDataObject("modulesettings");
var info = new SimplisityInfo(moduleData.Record);
}
<div class="w3-third w3-padding">
<label>Show Images</label>
@CheckBox(info, "genxml/settings/showimage", "", "class='w3-check'", true)
</div>
<div class="w3-third w3-padding">
<label>Show Categories</label>
@CheckBox(info, "genxml/settings/showcategories", "", "class='w3-check'", true)
</div>
Dependency File
RocketDirectory AppThemes have richer dependency files than RocketContent because they require the simplisity.js AJAX library, shared JS/CSS, paging/filter functionality, and queryparams for SEO and detail-URL activation.
Example from rocketdirectoryapi.Products:
<genxml>
<deps list="true">
<genxml>
<ctrltype>css</ctrltype>
<url>/DesktopModules/DNNrocket/css/w3.css</url>
<ecofriendly>true</ecofriendly>
<ignoreonskin>rocketw3</ignoreonskin>
</genxml>
<genxml>
<ctrltype>css</ctrltype>
<url>/DesktopModules/DNNrocket/Simplisity/css/simplisity.css</url>
<ecofriendly>true</ecofriendly>
</genxml>
<genxml>
<ctrltype>js</ctrltype>
<url>/DesktopModules/DNNrocket/Simplisity/js/simplisity.js</url>
<ecofriendly>true</ecofriendly>
</genxml>
<genxml>
<ctrltype>js</ctrltype>
<url>{appthemeshareddirectory}/js/w3shared.js</url>
<ecofriendly>true</ecofriendly>
</genxml>
<genxml>
<ctrltype>css</ctrltype>
<url>{appthemeshareddirectory}/css/w3shared.css</url>
<ecofriendly>true</ecofriendly>
</genxml>
<genxml>
<ctrltype>js</ctrltype>
<url>{jquery}</url>
<ecofriendly>true</ecofriendly>
</genxml>
</deps>
<moduletemplates list="true">
<genxml>
<file>view.cshtml</file>
<name>Full View</name>
<cmd>listdetail</cmd>
</genxml>
<genxml>
<file>listview.cshtml</file>
<name>List View</name>
<cmd>listdetail</cmd>
</genxml>
<genxml>
<file>Categories.cshtml</file>
<name>Category Menu</name>
<cmd>catmenu</cmd>
</genxml>
<genxml>
<file>ArticleSat.cshtml</file>
<name>Satellite</name>
<cmd>satellite</cmd>
</genxml>
</moduletemplates>
<adminpanelinterfacekeys list="true">
<genxml>
<interfacekey>articleadmin</interfacekey>
<show>true</show>
</genxml>
<genxml>
<interfacekey>categoryadmin</interfacekey>
<show>true</show>
</genxml>
<genxml>
<interfacekey>propertyadmin</interfacekey>
<show>true</show>
</genxml>
<genxml>
<interfacekey>settingsadmin</interfacekey>
<show>true</show>
</genxml>
</adminpanelinterfacekeys>
<queryparams list="true">
<genxml>
<queryparam>productscatid</queryparam>
<tablename>rocketdirectoryapi</tablename>
<systemkey>rocketdirectoryapi</systemkey>
<datatype>category</datatype>
</genxml>
<genxml>
<queryparam>productsid</queryparam>
<tablename>rocketdirectoryapi</tablename>
<systemkey>rocketdirectoryapi</systemkey>
<datatype>article</datatype>
</genxml>
</queryparams>
<menuprovider>
<genxml>
<assembly>RocketDirectoryAPI</assembly>
<namespaceclass>RocketDirectoryAPI.Components.MenuDirectory</namespaceclass>
<systemkey>rocketdirectoryapi</systemkey>
</genxml>
</menuprovider>
</genxml>
queryparams
The queryparams section is essential for RocketDirectory AppThemes. It tells the system:
- Which URL parameter holds a category or article ID.
- Which system and database table to query when that parameter is present.
- What type of data it represents (
articleorcategory).
This drives both SEO metadata injection (the detail page gets the article's title/description in the page <head>) and detail display activation (the module switches from list to detail view when the param is in the URL).
Each system derived from RocketDirectory uses its own param names (e.g. productsid, newsid, blogid) to avoid conflicts when multiple directory modules exist on the same page.
menuprovider
The menuprovider section connects the AppTheme's category data to the DNN DDR menu system, allowing categories to appear as DNN navigation items.
XPath Data Convention
| Data type | xPath |
|---|---|
| Plain text field | genxml/textbox/myfieldname |
| Localised text field | genxml/lang/genxml/textbox/myfieldname |
| Checkbox | genxml/checkbox/mycheckbox |
| Select / DropDown | genxml/select/myselect |
| Image (first) | article.GetImage(0) |
| Published date | genxml/textbox/publisheddate |
| Module setting | genxml/settings/mysetting |
SEO fields: For SEO to work automatically, use standard field names:
genxml/lang/genxml/textbox/articlenameorgenxml/lang/genxml/textbox/seotitlefor the meta title, andgenxml/lang/genxml/textbox/articlesummaryorgenxml/lang/genxml/textbox/seodescriptionfor the meta description.
cmd Values
The cmd value in moduletemplates determines what data is loaded for the module:
| cmd | Behaviour |
|---|---|
listdetail |
Loads list data; switches to detail data if an article URL param is present (default) |
listonly |
Loads list data only; never switches to detail |
detailonly |
Loads a single article only; no list |
catmenu |
Loads category data (no article data) |
satellite |
No data loaded; the template is responsible for its own AJAX data call |
Directory-Level Shared Templates
The appthemedirectory key accesses shared templates provided by the RocketDirectory system. These cover admin CRUD operations and standard UI blocks shared across all directory-based AppThemes:
| Shared Template | Purpose |
|---|---|
[INJECT:appthemedirectory,editbuttonbar.cshtml] |
Save/Cancel/Delete button bar for the admin detail form |
[INJECT:appthemedirectory,AdminSearch.cshtml] |
Search/filter bar for the admin list |
[INJECT:appthemedirectory,ArticleModelsBlock.cshtml] |
Custom field block; includes AdminExtra.cshtml from the AppTheme |
[INJECT:appthemedirectory,ArticleCategoryListBlock.cshtml] |
Category assignment panel |
[INJECT:appthemedirectory,ArticlePropertyListBlock.cshtml] |
Property/tag assignment panel |
[INJECT:appthemedirectory,ArticleimagesBlock.cshtml] |
Image management panel |
[INJECT:appthemedirectory,ArticleDocumentsBlock.cshtml] |
Document management panel |
[INJECT:appthemedirectory,ArticleLinksBlock.cshtml] |
Link management panel |
[INJECT:appthemedirectorydefault,articlePaging.cshtml] |
Front-end pagination control |
[INJECT:appthemedirectorydefault,SearchBanner.cshtml] |
Front-end search/sort/filter bar |