エクスプレスデータベース機能は便利ですが、標準では少しSEOに難がありますので、それを改善するカスタマイズの例をご紹介します。

title タグ、meta description タグの調整

エクスプレスデータベースエントリーの名前が title タグに追加されますが、任意の属性をタイトルに使いたかったり、meta description タグを追加したい場合もあるかと思います。

そのような際に、エントリーを表示しているエクスプレスエントリー詳細ブロックタイプのコントローラーをオーバーライドすることで、挙動を変更することが可能です。下記は、meta_title, meta_description というそれぞれの属性の値をエクスプレスデータベースエントリーから取得して使用しているカスタマイズ例になります。

<?php
namespace Application\Block\ExpressEntryDetail;

use Concrete\Core\Html\Service\Seo;
use Concrete\Core\Url\SeoCanonical;

class Controller extends \Concrete\Block\ExpressEntryDetail\Controller
{
    public function action_view_express_entity($exEntryID = null)
    {
        $entry = $this->entityManager->find('Concrete\Core\Entity\Express\Entry', $exEntryID);
        if (is_object($entry)) {
            $entity = $this->entityManager->find('Concrete\Core\Entity\Express\Entity', $this->exEntityID);
            if ($entry->getEntity()->getID() == $entity->getID()) {
                /** @var Seo $seo */
                $seo = $this->app->make('helper/seo');
                // Get the value of meta_title attribute of the entry
                $seo->setCustomTitle($entry->getMetaTitle());
                
                // Get the value of meta_description attribute of the entry
                $this->addHeaderItem('<meta name="description" content="' . h($entry->getMetaDescription()) . '">');

                /** @var SeoCanonical $canonical */
                $canonical = $this->app->make(SeoCanonical::class);
                $canonical->setPathArguments(['view_express_entity', $exEntryID]);

                $this->set('entry', $entry);
                $this->view();
            }
        }
    }
}

sitemap.xml にエクスプレスエントリー詳細ページのURLを追加する

エクスプレスエントリー一覧ブロックとエクスプレスエントリー詳細ブロックの組み合わせにより、エクスプレスデータベースの一覧と詳細のセットをサイト内に設置することが可能です。

ただし、この場合の詳細ページは、サイトマップとしては1つのページであり、ブロックが動的に内容をだし分けている形になります。そのため、sitemap.xml には含まれません。

sitemap.xml にこれらのページを追加したい場合は、application/bootstrap/app.php などから、on_sitemap_xml_ready イベントフックを利用して、sitemap.xml の生成時に処理を追加することが実現できます。

下記は、 /express/detail ページにエクスプレスエントリー詳細ブロックを置き、test オブジェクトのエントリーを全て sitemap.xml に追加するカスタマイズ例です。

<?php
/* @var Concrete\Core\Application\Application $app */
/* @var Concrete\Core\Console\Application $console only set in CLI environment */

/** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface $director */
$director = $app->make(\Symfony\Component\EventDispatcher\EventDispatcherInterface::class);
$director->addListener('on_sitemap_xml_ready', static function ($event) use ($app) {
    /** @var \Concrete\Core\Page\Sitemap\Event\XmlReadyEvent $event */
    $xml = $event->getDocument();

    $entity = Express::getObjectByHandle('test');
    if (is_object($entity)) {
        $resolver = $app->make(\Concrete\Core\Url\Resolver\Manager\ResolverManagerInterface::class);
        $list = new \Concrete\Core\Express\EntryList($entity);
        $entries = $list->getResults();
        /** @var \Concrete\Core\Entity\Express\Entry $entry */
        foreach ($entries as $entry) {
            $id = $entry->getID();
            $lastMod = $entry->getDateModified()->format(DateTime::ATOM);
            $url = $xml->addChild('url');
            $url->addChild('loc', $resolver->resolve(['/express/detail/', 'view_express_entity', $id]));
            $url->addChild('lastmod', $lastMod);
            $url->addChild('priority', 0.5);
            $url->addChild('changefreq', 'weekly');
        }
    }

    $event->setDocument($xml);
});