Andrew Welch · Insights · #craftcms #PhpStorm #twig

Published , updated · 5 min read ·


For more tools, technologies, and techniques, check out the devMode.fm podcast!

Auto-Complete Craft CMS 3 APIs in Twig with PhpStorm

The Sym­fony plu­g­in com­bined with a lit­tle mag­ic will give you full auto-com­plete of all Craft CMS APIs in your Twig tem­plates with PhpStorm!

Php­Storm is a fan­tas­tic edi­tor for devel­op­ing web-based projects as well as back­end projects.

I’ve men­tioned my use of Php­Storm in the So You Wan­na Make a Craft 3 Plu­g­in? arti­cle, and it’s equal­ly fan­tas­tic when you’re writ­ing fron­tend tem­plates, ES6 JavaScript, and even Twig.

One absolute­ly amaz­ing thing you can do in Php­Storm is get full auto-com­ple­tion of the entire craft. APIs in your Twig tem­plates, too! To do make the mag­ic hap­pen, install the Sym­fony plu­g­in, then Go to Pref­er­encesLan­guages & Frame­worksPHPSym­fony and check Enable Plu­g­in for this Project.

If you think you’ve seen this before, you probably haven’t. Carry on, intrepid reader!

Then all you need to do is put this inspec­tion hint at the top of your Twig templates:

{# @var craft \craft\web\twig\variables\CraftVariable #}

…and just like that, you get the same mag­ic auto-com­ple­tion of in your Twig tem­plates that you have in your PHP code. And since the entire Craft appli­ca­tion is avail­able in our Twig tem­plates now, this makes writ­ing Twig code that uses the Craft app APIs so much nicer.

So while this is nice, it can get a bit cum­ber­some to add that com­ment to every sin­gle tem­plate. Wouldn’t it be nice if there was a way that we could just add a file to our projects, and it’d all just mag­i­cal­ly work?

Just by having PhpStorm index a file, we can get auto-complete of everything!

Turns out, we can! Robin post­ed an issue a while back, and end­ed up with an answer from one of the Sym­fony plu­g­in devel­op­ers that works great. Here’s my mod­i­fied ver­sion of the file:

<?php
/**
 * FauxTwigExtension for Craft CMS 3.x
 *
 * This is intended to be used with the Symfony Plugin for PhpStorm:
 * https://plugins.jetbrains.com/plugin/7219-symfony-plugin
 *
 * It will provide full auto-complete for craft.app. and and many other useful things
 * in your Twig templates.
 *
 * Documented in the article:
 * https://nystudio107.com/blog/auto-complete-craft-cms-3-apis-in-twig-with-phpstorm
 *
 * Place the file somewhere in your project or include it via PhpStorm Settings -> Include Path.
 * You never call it, it's never included anywhere via PHP directly nor does it affect other
 * classes or Twig in any way. But PhpStorm will index it, and think all those variables
 * are in every single template and thus allows you to use Intellisense auto completion.
 *
 * Thanks to Robin Schambach; for context, see:
 * https://github.com/Haehnchen/idea-php-symfony2-plugin/issues/1103
 *
 * @link      https://nystudio107.com
 * @copyright Copyright (c) 2019 nystudio107
 * @license   MIT
 * @license   https://opensource.org/licenses/MIT MIT Licensed
 */

namespace nystudio107\craft;

/**
 * Class FauxCraftVariable extends the actual Craft Variable, but with added properties
 * that reflect things that are added to the Craft Variable dynamically by
 * plugins or modules.
 *
 * @property \craft\web\twig\variables\Cp $cp
 * @property \craft\web\twig\variables\Io $io
 * @property \craft\web\twig\variables\Routes $routes
 * @property \craft\web\twig\variables\CategoryGroups $categoryGroups
 * @property \craft\web\twig\variables\Config $config
 * @property \craft\web\twig\variables\Deprecator $deprecator
 * @property \craft\web\twig\variables\ElementIndexes $elementIndexes
 * @property \craft\web\twig\variables\EntryRevisions $entryRevisions
 * @property \craft\web\twig\variables\Feeds $feeds
 * @property \craft\web\twig\variables\Fields $fields
 * @property \craft\web\twig\variables\Globals $globals
 * @property \craft\web\twig\variables\I18N $i18n
 * @property \craft\web\twig\variables\Request $request
 * @property \craft\web\twig\variables\Sections $sections
 * @property \craft\web\twig\variables\SystemSettings $systemSettings
 * @property \craft\web\twig\variables\UserSession $session
 * @property \putyourlightson\blitz\variables\BlitzVariable $blitz
 * @property \nystudio107\twigpack\variables\ManifestVariable $twigpack
 * @mixin \craft\commerce\web\twig\CraftVariableBehavior
 *
 * @author    nystudio107
 * @package   nystudio107\craft
 * @since     1.0.2
 */
class FauxCraftVariable extends \craft\web\twig\variables\CraftVariable
{
}

/**
 * Class FauxTwigExtension provides a faux Twig extension for PhpStorm to index
 * so that we get Intellisense auto-complete in our Twig templates.
 *
 * @author    nystudio107
 * @package   nystudio107\craft
 * @since     1.0.2
 */
class FauxTwigExtension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
{
    public function getGlobals(): array
    {
        return [
            // Craft Variable
            'craft' => new FauxCraftVariable(),
            // Craft Elements
            'asset' => new \craft\elements\Asset(),
            'category' => new \craft\elements\Category(),
            'entry' => new \craft\elements\Entry(),
            'tag' => new \craft\elements\Tag(),
            // Craft "Constants"
            'SORT_ASC' => 4,
            'SORT_DESC' => 3,
            'SORT_REGULAR' => 0,
            'SORT_NUMERIC' => 1,
            'SORT_STRING' => 2,
            'SORT_LOCALE_STRING' => 5,
            'SORT_NATURAL' => 6,
            'SORT_FLAG_CASE' => 8,
            'POS_HEAD' => 1,
            'POS_BEGIN' => 2,
            'POS_END' => 3,
            'POS_READY' => 4,
            'POS_LOAD' => 5,
            // Misc. Craft globals
            'currentUser' => new \craft\elements\User(),
            'currentSite' => new \craft\models\Site(),
            'now' => new \DateTime(),
            // Commerce Elements
            'lineItem' => new \craft\commerce\models\LineItem(),
            'order' => new \craft\commerce\elements\Order(),
            'product' => new \craft\commerce\elements\Product(),
            // Third party globals
            'seomatic' => new \nystudio107\seomatic\variables\SeomaticVariable(),
        ];
    }
}

Put the file some­where in your project where Php­Storm will index it, and away you go! I put mine in src/php/FauxTwigExtension.php but it can be any­where that Php­Storm indexes.

The file is nev­er includ­ed by any­thing, the class is nev­er instan­ti­at­ed, and it doesn’t affect your project or Twig in any way.

It’s just a faux Twig exten­sion that Php­Storm index­es and thus Intel­lisense will auto-com­plete for us.

Pro tip: Make sure you’re not hav­ing Php­Storm ignore storage/runtime/compiled_classes in Pref­er­encesDirec­to­ries. That’s where Craft puts the gen­er­at­ed Behav­iors for your cus­tom fields.

Here’s what it gives us.

CRAFT VARI­ABLE

Craft Vari­able auto-completion

ENTRY

Entry auto-com­ple­tion

CAT­E­GO­RY

Cat­e­go­ry auto-completion

COM­MERCE PRODUCT

Com­merce Prod­uct auto-completion

SEO­MAT­IC

SEO­mat­ic auto-completion

That’s a pret­ty spiffy out of the box list of things to auto-com­plete. But the real­ly cool thing is you can add what­ev­er you want to the FauxTwigExtension.php file, let Php­Storm index it, and away you go!

Pret­ty sweet. I want to thank Robin for prod­ding me to write this up, and Oliv­er Stark for his help as well.

I hope it’s helpful!