To make things more clear in this document we'll use different namespace aliases.
use \Concrete\Core\Tree\Type\Topic as TopicTree;
use \Concrete\Core\Tree\Node\Node as TreeNode;
use \Concrete\Core\Tree\Node\Type\Topic as TopicTreeNode;
Getting an existing Topic
Getting an existing Topic is fairly simple:
$topic = TopicTreeNode::getNodeByName('News');
This will give us the Topic object.
Adding a new Topic
To add a new Topic to a given category we first need to get the Topic Tree where the category is in. In our case let's take the 'Blog Entries' Tree:
$topicTree = TopicTree::getByName('Blog Entries');
Then we get the category by its Tree Node ID by calling the getRootTreeNodeObject()
method & the ID from the Topic Tree object we called before. That way we get the first category called 'Category':
$topicCategory = TreeNode::getByID($topicTree->getRootTreeNodeObject()->treeNodeID);
Or if we want another category we call it by its handle, for example 'Reviews':
use Concrete\Core\Attribute\Key\Category;
$topicCategory = new Category();
$topicCategory->getByHandle('Reviews');
Now we can add a new Topic, let's call it 'Leisure' to that before called category:
$topic = TopicTreeNode::add('Leisure', $topicCategory);
Binding a Topic to a Page
Finally, we want that Topic to be useful, say for a Blog Entry Page. To bind a Topic to a Page we first need to call the desired Page object by its ID or path (The page ID is shown in the Sitemap, when selecting a Page and clicking "Attributes" in the top right corner).
To read on how to work with Pages, please refer to the documentation page Working with Pages Programmatically. So let's call our Page object by its ID:
$blogEntryPage = \Page::getByID(172);
Then we need the Attribute type, which is in our case 'topics';
use Concrete\Core\Attribute\Type as AttributeType;
$attributeType = AttributeType::getByHandle('topics');
Next, we need the CollectionAttributeKey
to activate that Attribute in the page. In our case it's the 'blog_entry_topics':
$attributeKey = CollectionAttributeKey::getByHandle('blog_entry_topics');
From that we need the handle by calling:
$akHandle = $attributeKey->getAttributeKeyHandle();
Now we are ready to activate our Attribute and the Topic. So from our page object we do:
$blogEntryPage->setAttribute($akHandle, $topic->getTreeNodeDisplayPath());