Topics - Select first by default

Permalink 1 user found helpful
Hello,

Can someone help me make a custom topic template that selects the first topic in the tree by default if no other topic has been selected? I want to mimic the effect of "replace_link_with_first_in_nav" but with topics. So when I go to my page, it will auto select the first topic and filter the associated page list block.

I'm guessing it has something to do with the "getTopicLink" function but I'm not that experienced to see the solution clearly.


Thank you

GBNT
 
GBNT replied on at Permalink Reply
GBNT
Ok, I was able to resolve this by changing the foreach loop inside the topic_list template to this:
<?php foreach($node->getChildNodes() as $child) { 
            if (!isset($selectedTopicID)){ 
                $defaultTopic = $view->controller->getTopicLink($child);
                header("Location: $defaultTopic");
                end();
            } else { ?>
                <li><a href="<?php echo $view->controller->getTopicLink($child)?>"
                    <?php if (isset($selectedTopicID) && $selectedTopicID == $child->getTreeNodeID()) { ?>
                        class="ccm-block-topic-list-topic-selected active"
                    <?php } ?> ><?php echo $child->getTreeNodeDisplayName()?></a></li>
            <?php } 
        } ?>


I'm leaving the question open because there might be a Concrete5 way of doing this, if so I would like to know.
daenu replied on at Permalink Reply
daenu
Hi
I struggled on this too. It isn't documented yet. The solution from GBNT is (sorry to have to say) an absolute NO-GO because you never ever should have to use a controller function for things like that.

// Get the topic by name
$topic = TopicTreeNode::getNodeByName('topic_name');
// Or the first one
$db = Loader::db();
$row = $db->GetOne('select treeNodeTopicName from TreeTopicNodes Order By treeNodeID asc Limit 1,1');
$topic = TopicTreeNode::getNodeByName($row);
// Get the page instance by ID or path
$page = Page::getById(1);
// OR
$page = Page::getByPath('path/to/page');
// Get the tree ID
$db = Loader::db();
$treeID = $db->GetOne('select treeID from TopicTrees where topicTreeeName = ?', array('Topc Tree Name');
$tree = TopicTree::getById($treeID);
// Set the page Attribute
GBNT replied on at Permalink Reply
GBNT
Hi Daenu,

I'm a designer, not a developer so it's ok to say my solution is a no-go. :) I left this open for that exact reason.
Could you explain why using the view controller here is a bad idea?

Does your code go in the Topic List block template?
Will phave to look at it in the morning.

Cheers
daenu replied on at Permalink Reply
daenu
Hi GBNT

So first of all, Yes I think you may override the Page List block into the /application folder and add the above code there. It's untested because I use it in a package, but with some minor changes it should work.

The second thing, about that controller thing, is that the software architecture of concrete5 is made in the MVC style. That means Model-View-Controller (https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller).

The controller's task is to pass data to a view (user interface) and processing data from the view. Means that for example if you check the box beside of a topic and hit "Save Changes" in the page's attributes section, then the controller comes into the game. It validates the data being sent by the form and if everything is ok it passes then the data to the model(s) which are doing other stuff & finally save data into the Database. So it should never be used for other things than that.