nystudio107 / craft-seomatic

SEOmatic facilitates modern SEO best practices & implementation for Craft CMS 3. It is a turnkey SEO system that is comprehensive, powerful, and flexible.
https://nystudio107.com/plugins/seomatic
Other
165 stars 70 forks source link

Exclude entries via an event hook? #1393

Closed anchovy closed 10 months ago

anchovy commented 10 months ago

Question

We've got a large site and we want to exclude content from the sitemaps based on url structure rather than via sections for example: Include: test.com/public Exclude test.com/members

Is there an event we could use for this, potentially https://nystudio107.com/docs/seomatic/advanced.html#registersitemapurlsevent

Additional context

Craft Pro: 4.5.9 SEOmatic: 4.0.33

khalwat commented 10 months ago

No, that event won't work for your purpose.

What elements (Entry's, etc.) have the members directory as their URI? Can you just turn off Sitemaps for that section?

anchovy commented 10 months ago

Hi @khalwat - thanks for the super quick reply!

The public and members both use the same section types. I see you can manually disable the entry showing in the site map via the 'SEO' tap per entry:

image

Can I programmatically enable this via the EVENT_BEFORE_SAVE, how do I access the variable to

  1. set Sitemap Enabled Override = true
  2. Set Whether URLs in this entry should be included in the sitemap = false

Event::on(
    Entry::class,
    Entry::EVENT_BEFORE_SAVE,
    function (ModelEvent $event) {
        $entry = $event->sender;

        if (ElementHelper::isDraftOrRevision($entry)) {
            return false;
        }

        /**
         * TODO
         * if this url stats with /members then exclude from the site map.
         */
 });
anchovy commented 10 months ago

@khalwat - think I've got it.

        Event::on(
            Element::class,
            Element::EVENT_BEFORE_SAVE,
            function (ModelEvent $event) {

                if (ElementHelper::isDraftOrRevision($event->sender)) {
                    return false;
                }

                if (!$event->sender->propagating) {

                    if ($event->sender->uri !== null) {
                        $uri = $event->sender->uri;

                        // Check if the URI begins with 'members'
                        if (isset($event->sender->seo) && strpos($uri, 'members') === 0 ) {

                            if(isset($event->sender->seo->metaSitemapVars->inherited['sitemapUrls']))
                            {
                                unset($event->sender->seo->metaSitemapVars->inherited['sitemapUrls']);
                                $event->sender->seo->metaSitemapVars->overrides['sitemapUrls'] = true;
                            }

                        }
                    }

                }
            }
        );
anchovy commented 10 months ago

mmm... Actually this is only working if you make a change to one of the seo fields. With a 'new' entry and nothing changed on the seo field the changes don't stick.

khalwat commented 10 months ago

Yeah I think a better way to do this would be for me to add an event triggered by the sitemap, which you can then listen to and decide whether the item should be included in the sitemap or not.

khalwat commented 10 months ago

Added in: https://github.com/nystudio107/craft-seomatic/commit/7ba59fb680be0e0dce238e70815eec0e8b60c6d6 & https://github.com/nystudio107/craft-seomatic/commit/78c89d8c25f89d20375dd3163832b727e1c2bead

Craft CMS 3:

You can try it now by setting your semver in your composer.json to look like this:

    "nystudio107/craft-seomatic": "dev-develop as 3.4.68”,

Then do a composer clear-cache && composer update

…..

Craft CMS 4:

You can try it now by setting your semver in your composer.json to look like this:

    "nystudio107/craft-seomatic": "dev-develop-v4 as 4.0.37”,

Then do a composer clear-cache && composer update

Let me know how this works for you... docs ->

IncludeSitemapEntryEvent

const EVENT_INCLUDE_SITEMAP_ENTRY = 'IncludeSitemapEntryEvent';

The event that is triggered when an entry is about to be included in a sitemap.

    use nystudio107\seomatic\events\IncludeSitemapEntryEvent;
    use nystudio107\seomatic\helpers\Sitemap;
    use yii\base\Event;
    Event::on(Sitemap::class, Sitemap::EVENT_INCLUDE_SITEMAP_ENTRY, function(IncludeSitemapEntryEvent $e) {
        $e->include = false;
    });
anchovy commented 9 months ago

Hi @khalwat - This works a treat - thanks, when will this be officially released?

khalwat commented 9 months ago

I need to do some more testing on a few other things, but likely early next week.