Adding custom content types to Universe Search

In order to add new content types to the Control Center's Universe Search, they must first be registered in the Jadu system. The content type can then be linked up to Universe Search.

I've used the News content type from publishing in this example, but you can add entries for any custom content type.

Adding a Content Type


First, you will need to define the ItemWrapper for an instance of the content type. This is a class which provides a common interface for Universe Search (and other areas of the CMS) to interact with a Content Type Item.

The ItemWrapper exposes methods to retrieve URLs for editing and preview of the content item as well as methods to carry out actions such as delete, change ownership, lock and unlock.

The class will need to extend the base class Jadu_ContentType_ItemWrapper and must, as a minimum, implement all of the abstract methods in that class. See method comments in the base class for more details on each.

Sample implementations from the websections/ItemWrapper/NewsArticle.php:

protected function getLive ()
{
return $this->getContentItem()->live;
}

public function getLiveURL ()
{
$url = "";
if ($this->canViewLive()) {
$url = buildNewsArticleURL($this->getID(), 
true, 
$this->getTitle());
}
return $url;
} public function delete () { deleteNews($this->getID()); }
public function loadItem ($itemID)
{
$this->contentItem = getNews($itemID);
}

The static function getInstance() must also be implemented. This will be used to instantiate the ItemWrapper:

public static function getInstance(ADOConnection $db, Jadu_ContentType $contentType, $itemID)
{
$news = getNews($itemID);
return new Jadu_Websections_ItemWrapper_NewsArticle(
$db, 
$contentType, 
$news);
}

Implement the methods to fit the functionality of your type - if you haven't implemented any preview for example, just hard-code 'return false;' in the canPreview() method. The core content types all have ItemWrappers and so you should be able to find one similar to your needs to reference.

Once complete, add a record to the JaduContentTypes database table to provide basic information about the content type and the name and location of the ItemWrapper above.

INSERT INTO `JaduContentTypes` (
`singularName`, `pluralName`, `tableName`, 
`icon`, `createURL`, `editURLTemplate`, 
`categoriesTable`, `appliedCategoriesTable`, 
`createNewPriority`, `groupLabel`, 
`itemWrapperClass`, `itemWrapperFile`
)
VALUES (
'News Article', 'News Articles', 'JaduNews', 
'news.png', '/websections/websection_news.php', '/websections/websection_news.php?newsID=%d', 
'JaduNewsCategories', 'JaduNewsAppliedCategories', 
5, 'contentLabel', 
'Jadu_Websections_ItemWrapper_NewsArticle', 'websections/ItemWrapper/NewsArticle.php'
);

After clearing the Jadu cache for JaduContentTypes, your new content type should be available in the 'New' menu in the mast of the Control Center (you will probably need to go into the 'customise' menu to find it).

(note: the menu is filtered based on admin access permissions, so make sure you have module page records for the createURL and your CMS admin has been granted access to it.)

Universe Search


Now we have the content type in the system, you need to tell Universe Search how to interact with it.

The SearchProvider class is required to determine the mapping between the ContentType’s database tables and Universe Search. It will provide a list of fields to search, identify which fields are titles, modification dates and owner IDs and specify mappings to other tables if necessary (e.g. Documents to Document Headers and Document Pages).

The class should extend the base class Jadu_Search_Provider and should implement the loadTables() method.

All of the ContentTypes available to the current administrator are made available to this method. Whether or not the admin has access is determined by the content type's editURLTemplate - so this needs to match a module page record that your admin has been granted access to.

It is suggested that one SearchProvider is written per module and handles mappings for all types in that module. The example below shows only News, but all of the publishing ContentTypes are handled by the full version of this class.

websections/SearchProvider.php:

class Jadu_Websections_SearchProvider extends Jadu_Search_Provider {
protected function loadTables ()
{
foreach ($this->getContentTypes() as $contentType) { /* @var $contentType Jadu_ContentType */
$table = new Jadu_Search_TableMapping($this->db);
$table->setContentType($contentType);
switch ($contentType->getTableName()) {
case "JaduNews":
$table->setSearchFields(array("main.title", "main.summary", "main.content"));
$table->setOwnerField("main.adminID");
$table->setModDateField("main.modDate");
$table->setMetadataTable("JaduNewsMetadata");
$this->addTableMapping($table);
break;

}
}
}
}

The table for the content type is always aliased as 'main'.

Finally, a record referencing the SearchProvider will need to be added to JaduSearchProviderEntries.

INSERT INTO `JaduSearchProviderEntries` (
`className`, `classFile`
)
VALUES (
'Jadu_Websections_SearchProvider', 'websections/SearchProvider.php'
);

Clear the Jadu cache for JaduSearchProviderEntries and you should then be able to find items of your new type using the Universe Search box.


General Concept: 
Jadu Product: 
Jadu Version: