Building a Craft CMS Dashboard Widget

Customizing the Widget

Ryan populates the widget with dynamic content from the Craft Deprecator service, uses the UrlHelper to create a CP URL, and more.

The first thing I want to do is fix the name of the wid­get. The default name is the class name, as you can see from the Pas­cal­Cased name, which match­es our class name.

Let’s cre­ate a bet­ter name to dis­play there. We do that using a sta­t­ic method in our wid­get class file called displayName().

This sta­t­ic method will return the name of the Wid­get, as defined by us. 

At the top of our DeprecWidget class file:

public static function displayName(): string
{

	
}

This method returns the name of the wid­get as a string that we define. We’ll keep it sim­ple and not wor­ry about trans­la­tions at this point, just return­ing a sim­ple string.

public static function displayName(): string
{
	
	return "Deprecation Warnings";
	
}

If we reload the dash­board, we’ll see the name update. This name changes even with­out instan­ti­at­ing a new wid­get because the name is called from a sta­t­ic class method.

Now let’s address the con­tent of the wid­get. We see this sil­ly graph­ic because we don’t have any HTML set to dis­play. This is the place­hold­er that Craft pro­vides to us. We’ll update the wid­get title and body con­tent to make it func­tion­al for its purpose.

Set­ting a displayName

The displayName() method pro­vides the main name of the wid­get. This dis­play name shows in the Add Wid­get drop-down and in the wid­get itself unless we spec­i­fy a wid­get title.

In our wid­get, I don’t want to show the name of the wid­get in the wid­get because it’s not help­ful infor­ma­tion. We’ll have oth­er copy there that will let the user know the con­text of the widget. 

We could blank out the returned val­ue of displayName() but it is need­ed else­where in the CP, so we’ll that. Instead, we’ll define the wid­get title using the getTitle() method from the par­ent class. 

public function getTitle(): string
{
	return '';
}

Instead of return­ing the name of the wid­get, we’ll return an emp­ty string.

Adding Wid­get Body Content

Now we can focus on the main con­tent of the wid­get. This could any­thing you can do in HTML and PHP and will vary by wid­get. We’re going to dis­play the num­ber of dep­re­ca­tion warn­ings and some helper text for our wid­get, so it’s clear what the num­ber means.

We tell the wid­get what to dis­play using the getBodyHtml() method. This is a method that we set in our wid­get class that over­rides the same method in the base Wid­get class that we’re extending.

This method returns a string con­tain­ing the HTML that we want the wid­get to ren­der. For right now, we will return a sim­ple string of HTML with some styling. Lat­er on, in the course, we’ll use a twig tem­plate in our wid­get to make that a bit eas­i­er to maintain.

public function getBodyHtml(): string
{
	return "<div class='centeralign'><h2 style='font-size:3rem;'>10</h2><p class='centeralign'>deprecationswarnings to address.</p></div>";
}

We now have a sim­ple lay­out with a large num­ber and some micro­copy to explain the number.

The next step is to make the dep­re­ca­tion warn­ing num­ber dynam­ic and fed from a Craft service.

In Craft we have access to the Dep­re­ca­tor ser­vice via a trait called getDeprecator(). The ser­vice has a method called getTotalLogs(), which is per­fect for our needs! 

First, let’s import the main Craft class in our wid­get class.

use Craft;

And then, we’ll set the val­ue of the total logs to the vari­able count. And use a string inter­po­la­tion to out­put the val­ue of count.

public function getBodyHtml(): string
{
	$count = Craft::$app->getDeprecator()->getTotalLogs();

	return "<div class='centeralign'><h2 style='font-size:3rem;'>10</h2><p class='centeralign'>deprecation warnings to address.</p></div>";
}

And now, if we reload the dash­board, we should see it pop­u­late with a dep­re­ca­tion warn­ing! As a side note: I put some code in the index tem­plate of this Craft instal­la­tion with inten­tion­al­ly incor­rect Twig code so we’d get at least one dep­re­ca­tion warn­ing to test with.

This set­up with just a string of text as HTML isn’t ide­al, but we’ll fix that up in a lat­er video and refac­tor this to use tem­plates instead of the cur­rent implementation.

Link­ing to Oth­er CP Pages

I’d also like to have a way for some­one to link off right to the dep­re­ca­tion warn­ings page in the con­trol pan­el and see what’s going on. 

Let’s cre­ate a but­ton that links off to the dep­re­ca­tion warn­ing page. We’ll just use sim­ple markup here:

<p><a class='btn small' href=''>Review and Fix</a></p>

We’ll add it to our exist­ing markup.

public function getBodyHtml(): string
{
	$count = Craft::$app->getDeprecator()->getTotalLogs();

	return "<div class='centeralign'><h2 style='font-size:3rem;'>10</h2><p class='centeralign'>deprecation warnings to address.</p><p><a class='btn small' href=''>Review and Fix</a></p></div>";
}

To get the URL of the dep­re­ca­tion warn­ings page in the Con­trol Panel’s Util­i­ties sec­tion, we need to first import the UrlHelper class from Craft and then use it to gen­er­ate a URL with the URL path.

use craft\helpers\UrlHelper; 
public function getBodyHtml(): string
{
	$count = Craft::$app->getDeprecator()->getTotalLogs();
	$deprecUrl = UrlHelper::url('utilities/deprecation-errors');
	return "<div class='centeralign'><h2 style='font-size:3rem;'>10</h2><p class='centeralign'>deprecation warnings to address.</p><p><a class='btn small' href='{$deprecUrl}'>Review and Fix</a></p></div>";
}

We just need to reload the dash­board, and the but­ton works!

Building a Craft CMS Dashboard Widget is made up of the following videos: