In diesem Beispiel möchte ich anhand des Topic_List Blockes erläutern, wie man sehr schnell den Controller des Blockes überlagert/ableitet um updatesicher zu bleiben.
Augabenstellung:
Die Topic_List soll verwendet werden, um Themen-Einträge aufzuzeigen, jedoch sollen nicht nur die bei den Seitenattributen selektierten EInträge erscheinen, sondern auch die NICHT selektierten. Dazu muss der concrete5 Topic_List Controller erweitert.
Vorgehensweise:
1. controller.php aus concrete/blocks/topic_list kopieren nach application/blocks/topic_list
2. controller.php unter application bereinigen:
- alle Funktionen löschen, die nicht überlagert werden sollen, auch überflüssige use Anweisungen
- Am Dateianfang namespace und abgeleiteten Klassennamen definieren (use Anweisung), Klassennamen festlegen
namespace Application\Block\TopicList;
use Concrete\Block\TopicList\Controller as TopicListBlockController;
class Controller extends TopicListBlockController { ...
}
3. eigenen Code schreiben, in diesem Fall alle Themeneinträge auslesen, nicht nur die, die in auf der Seite bei den Attributen selektiert sind (bei Mehrfachselektion):
// Hole alle Themeneinträge zu einer Kategorie und liefere diese als Objekt-Array zurück
private function getTopics($topicTreeName, &$CategoryName)
{
$key = new CollectionKey();
$this->requireAsset('core/topics');
$tt = new TopicTree();
$tree = $tt->getByName($topicTreeName);
$node = $tree->getRootTreeNodeObject();
$ak_t = $key->getByHandle($this->topicAttributeKeyHandle);
$vglID = $ak_t->getAttributeKeyID();
$CategoryName = '';
$node->populateChildren();
$alltopics = [];
foreach ($node->getChildNodes() as $topic) {
if ($topic instanceof \Concrete\Core\Tree\Node\Type\Category) {
$ak_t = $key->getByHandle($topic->getTreeNodeName());
$topicID = $ak_t->getAttributeKeyID();
if ( $topicID == $vglID ) {
$CategoryName = $topic->getTreeNodeDisplayName();
foreach ($topic->getChildNodes() as $topicm)
{
$alltopics[] = $topicm;
}
}
}
}
return $alltopics;
}
neue privat Funktion in view() aufrufen:
public function view()
{
// .....
$page = \Page::getCurrentPage();
$topics = $page->getAttribute($this->topicAttributeKeyHandle);
if (is_array($topics)) {
$this->set('topics', $topics);
}
$ThemenKatalogName = '';
$tnode = new TopicTreeNode();
$catNode = $tnode->getNodeByName($this->topicAttributeKeyHandle);
$rootNode = $catNode->getTreeObject()->getRootTreeNodeObject();
$ThemenKatalogName = $rootNode->getTreeObject()->getTreeName();
if ( !empty($ThemenKatalogName)) {
$CategoryName = '';
// Input: Themenkatalog, Output: Kathegorie-Name, Return: Object Array
$alltopics = $this->getTopics('Produktoptionen', $CategoryName);
if (is_array($alltopics)) {
if (is_array($topics)) {
foreach ($topics as $topic) {
$idx=0;
foreach ($alltopics as $alltopic) {
if ( $alltopic->getTreeNodeID() == $topic->getTreeNodeID()) {
// nicht das Object loeschen, nur aus array aushängen
unset($alltopics[$idx]);
$alltopics = array_values($alltopics);
break;
}
$idx++;
}
}
}
$this->set('notselectedtopics', $alltopics);
$this->set('categoryName', $CategoryName);
}
}
// ...
}
4. Neues Template machen oder ein vorhandenes ändern (Auswahl über Designvorlage Kontextmenü)
Jetzt kann im entsprechenden Theme-Block-Template auf die Variablen zugegriffen werden. Das Template befindet sich meist im Theme Bereich unter packages.
$notselectedtopics // Object Array
$categoryName // String
foreach ($notselectedtopics as $notsel) {
echo '<li class="circle-unchecked">' . $notsel->getTreeNodeDisplayName() . '</li>';
}

