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