cp-nav icon indicating copy to clipboard operation
cp-nav copied to clipboard

Combining with a module that adds custom items

Open JayBox325 opened this issue 9 months ago • 2 comments
trafficstars

Question

I have got a unique multi-site setup where each site has a different 'homepage' single, but my platform could end up with 15/20 or more sites, so in an attempt to limit how complex my permissions management could get and to try to simplify the onboarding process of a new site, I have written a module that automates adding a link to the singles associated with that site to the global sidebar.

Your 'Expanded Singles' plugin didn't work for me as we're not using the secondary sidebar, and hosting everything in the global sidebar.

The benefits of this module mean I can have just one 'outlets' Navigation layout that is associated with one 'outlet' user group, whereas if I don't use my module.

In order to get the AX I'm looking for, I'd need to create a new site, a new user group, a new single and a new navigation layout for each outlet which will become hard to maintain, whereas if I can just dynamically add the singles to the top, this will save a lot of work. Here is my module that finds the singles for the current site and adds them to the sidebar, but when I enable the Navigation plugin, it replaces this item, too. Is it going to be possible to combine them?

<?php

namespace sidebarsingle;

use Craft;
use craft\events\RegisterCpNavItemsEvent;
use craft\models\Section;
use yii\base\Event;
use craft\elements\Entry;

class Module extends \yii\base\Module
{
    public function __construct($id, $parent = null, array $config = [])
    {
        parent::__construct($id, $parent, $config);

        // Attach the event handler when the module is initialized
        Craft::$app->onInit(function () {
            $this->registerEventHandlers();
        });
    }

    private function registerEventHandlers()
    {
        // Listen for the CP navigation item registration event
        Event::on(
            \craft\web\twig\variables\Cp::class,
            \craft\web\twig\variables\Cp::EVENT_REGISTER_CP_NAV_ITEMS,
            function (RegisterCpNavItemsEvent $event) {
                // Fetch all singles for the current site
                $singles = $this->getCurrentSiteSingles();

                // Add a navigation item for each single
                foreach ($singles as $single) {
                    array_unshift($event->navItems, [
                        'url' => 'entries/' . $single->section->handle . '/' . $single->id . '-' . $single->slug, // URL for the single
                        'label' => 'Landing Page',
                        'icon' => '@appicons/house.svg', // Optional icon
                    ]);
                };

            }
        );
    }

    /**
     * Fetch all singles for the current site
     *
     * @return array The singles for the current site
     */
    private function getCurrentSiteSingles()
    {
        // Get the currently active site
        $currentSiteHandle = Craft::$app->getRequest()->getParam('site', Craft::$app->getSites()->getCurrentSite());
        $currentSite = Craft::$app->getSites()->getSiteByHandle($currentSiteHandle);

        if ($currentSite) {
            // Get the current site's ID
            $currentSiteId = $currentSite->id;

            // Fetch all singles
            $singles = Craft::$app->entries->getSectionsByType(Section::TYPE_SINGLE);

            // Find the single for the current site and return it
            $singlesForCurrentSite = array_filter($singles, function ($single) use ($currentSiteId) {
                return in_array($currentSiteId, $single->getSiteIds());
            });

            // Fetch the associated entries to get the slugs
            $entries = [];
            foreach ($singlesForCurrentSite as $single) {
                $entry = Entry::find()
                    ->sectionId($single->id) // Filter by the section ID
                    ->siteId($currentSiteId) // Ensure it's for the current site
                    ->one();

                if ($entry) {
                    $entries[] = $entry;
                }
            }

            return $entries;

        } else {
            echo 'Error: Active site not found.';
            return [];
        }
    }
}

Thanks!

Additional context

No response

JayBox325 avatar Jan 28 '25 23:01 JayBox325