Advanced: Customizing the Behavior of the Help Message Display

Note: this requires Concrete CMS 7.5 or later

When registering a message in a centralized help registry, we have been using the method registerMessageString(), since it's convenient and usually little more than this is needed. However, if you want greater control over how your message appears asnd works within the help overlay, you can pass a message object in directly. Change this:

public function register()
{
    $this->app['help/dashboard']->registerMessageString('/dashboard/acme\_widgets/add',
        t('Add a Widget.')
    );
}

to this:

public function register()
{
    $message = new \Concrete\Core\Application\Service\UserInterface\Help\Message();
    $message->addGuide('add-calendar');
    $message->setMessageContent(t('Add a widget.'));
    $this->app['help/dashboard']->setMessage('/dashboard/acme\_widgets/add', $message);
}

This gets us the same behavior. But what gets interesting is when we eschew the built-in Message class entirely, for something of our own making. Let's say we have a custom help message that might add different display formatting or new options entirely to the help message output, contained within our package at \Concrete\Package\AcmeWidgets\Help\Message(). Perhaps we're implementing some cross-linking via a completely new method called "setCrossLinkedSection()."

public function register()
{
    $message = new \Concrete\Package\AcmeWidgets\Help\Message();
    $message->setMessageContent(t('Add a widget.'));
    $message->setCrossLinkedSection('/dashboard/acme_widgets/list');
    $this->app['help/dashboard']->setMessage('/dashboard/acme\_widgets/add', $message);
}

All we have to do is make sure that the object we pass to the setMessage() method as its second parameter implements the \Concrete\Core\Application\Service\UserInterface\Help\Message\MessageInterface interface. This takes care of ensuring that we have the ability to print out messages, set identifiers and more. The rest is up to us. Our message class might look like this:

<?php
namespace Concrete\Package\AcmeWidgets\Help;

class Message implements MessageInterface
{
    protected $content;
    protected $crosslink;
    protected $identifier;

    /**
     * @return mixed
     */
    public function getContent()
    {
        $content = new \HtmlObject\Element('div');
        $content->setChild(new \HtmlObject\Element('p', $this->content));
        if ($this->crosslink) {
            $linkedPage = \Page::getByPath($this->crosslink, 'ACTIVE');
            $content->setChild(id(new \HtmlObject\Link($this->link, $linkedPage->getCollectionName()))->target('blank'));
        }
        return $content;
    }

    /**
     * @param mixed $content
     */
    public function setMessageContent($content)
    {
        $this->content = $content;
    }

    /**
     * @return mixed
     */
    public function getIdentifier()
    {
        return $this->identifier;
    }

    /**
     * @param mixed $identifier
     */
    public function setIdentifier($identifier)
    {
        $this->identifier = $identifier;
    }

    public function setCrossLinkedSection($crosslink)
    {
        $this->crosslink = $crosslink;
    }

}

Even though we've added new functionality to this custom message class, since it implements the MessageInterface class, Concrete knows it can be trusted to output correctly. We implement our custom crosslinking functionality, confident that our new class will work in the existing help system.