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>'; }