Provides Twig template IDE autocomplete of Craft CMS & plugin variables

Overview

Scrutinizer Code Quality Code Coverage Build Status Code Intelligence Status

Autocomplete for Craft CMS 3.x

Provides Twig template IDE autocompletion for Craft CMS and plugin/module variables and element types.

Works with PhpStorm provided the Symfony Support plugin is installed. VSCode currently does not support intellisense for Twig extensions.

While Craft 3.7.8 added autocompletion for Craft’s global Twig variables, this does not include autocompletion for plugins and modules that provide their own variables or element types.

demo

Requirements

This plugin requires Craft CMS 3.0.0 or later.

Usage

  1. Install the package using composer.
composer require nystudio107/craft-autocomplete
  1. Ensure that the Symfony Support plugin for PhpStorm is installed and enabled.

  2. Ensure that devMode is enabled.

  3. Visit the Craft site on which the package is installed to generate the autocomplete classes in storage/runtime/compiled_classes/ or run the following console command.

php craft autocomplete/generate

Once your IDE indexes the autocomplete classes, autocompletion for Craft and all plugins and modules will immediately become available in your Twig templates.

screenshot

Additionally, autocompletion for element types provided by both Craft and plugins/modules is available, for example: asset, entry, category, tag, user, product (if Craft Commerce is installed), etc.

N.B.: If you are using a Docker-ized setup, ensure that storage/runtime/compiled_classes/ is bind mounted on your client machine, so your IDE can find the classes to index them

Regenerating Autocomplete Classes

The autocomplete classes are all generated any time Craft executes (whether via frontend request or via CLI), if they do not yet exist.

The autocomplete classes are all regenerated every time you install or uninstall a plugin.

If you manually add a plugin or module that registers variables on the Craft global variable, you can force the regeneratation of the autocomplete classes by running the following console command.

php craft autocomplete/regenerate

...or since the autocomplete classes are automatically regenerated if they don’t exist, you can clear the Runtime caches with:

php craft clear-caches/temp-files

Extending

In addition to the provided autocomplete generator types, you can write your own by implementing the GeneratorInterface class or extending the abstract Generator class (recommended).

<?php
namespace vendor\package;

use nystudio107\autocomplete\base\Generator;

class MyAutocompleteGenerator extends Generator
{
    // Override base methods
}

To register your generator type, listen for the EVENT_REGISTER_AUTOCOMPLETE_GENERATORS event and add your class to the types property.

use nystudio107\autocomplete\Autocomplete;
use craft\events\RegisterComponentTypesEvent;
use yii\base\Event;

Event::on(Autocomplete::class,
    Autocomplete::EVENT_REGISTER_AUTOCOMPLETE_GENERATORS,
    function(RegisterComponentTypesEvent $event) {
        $event->types[] = MyAutocompleteGenerator::class;
    }
);

See the included generators for guidance on how to create your own.

How It Works

On the quest for autocomplete in the PhpStorm IDE, Andrew wrote an article years ago entitled Auto-Complete Craft CMS 3 APIs in Twig with PhpStorm

This worked on principles similar to how Craft Autocomplete works, but it was a manual process.
Ben and Andrew thought they could do better.

Bootstrapping Yii2 Extension

This package is a Yii2 extension (and a module) that bootstraps itself.

This means that it’s automatically loaded with Craft, without you having to install it or configure it in any way.

It only ever does anything provided that devMode is enabled, so it’s fine to keep it installed on production.

The Generated Autocomplete Classes

All Craft Autocomplete does is generate source code files, very similar to how Craft itself generates a CustomFieldBehavior class in storage/runtime/compiled_classes

The code that is generated by Craft Autocomplete is never run, however. It exists just to allow your IDE to index it for autocomplete purposes.

During the bootstrapping process, the package generates two classes, AutocompleteTwigExtension and AutocompleteVariable, if they do not already exist or if a Craft plugin was just installed or uninstalled.

The AutocompleteTwigExtension class is generated by evaluating all the Twig globals that have been registered. The AutocompleteVariable class is generated by dynamically evaluating the global Craft variable, including any variables that have been registered on it (by plugins and modules).

Here’s an example of what the files it generates might look like, stored in storage/runtime/compiled_classes:

AutocompleteVariable.php:

<?php

namespace nystudio107\autocomplete\variables;

/**
 * Generated by Craft Autocomplete
 *
 * @property \craft\web\twig\variables\Cp $cp
 * @property \craft\web\twig\variables\Io $io
 * @property \craft\web\twig\variables\Routes $routes
 * ...
 * @property \modules\sitemodule\variables\SiteVariable $site
 * @property \nystudio107\imageoptimize\variables\ImageOptimizeVariable $imageOptimize
 * @property \putyourlightson\blitz\variables\BlitzVariable
 */
class AutocompleteVariable extends \craft\web\twig\variables\CraftVariable
{
}

AutocompleteVariable.php:

<?php

namespace nystudio107\autocomplete\twigextensions;

/**
 * Generated by Craft Autocomplete
 */
class AutocompleteTwigExtension extends \Twig\Extension\AbstractExtension implements \Twig\Extension\GlobalsInterface
{
    public function getGlobals(): array
    {
        return [
            'craft' => new \nystudio107\autocomplete\variables\AutocompleteVariable(),
            'currentSite' => new \craft\models\Site(),
            'currentUser' => new \craft\elements\User(),
            // ...
            'seomatic' => new \nystudio107\seomatic\variables\SeomaticVariable(),
            'sprig' => new \putyourlightson\sprig\variables\SprigVariable(),
        ];
    }
}

The Symfony Support Plugin for PhpStorm

The other half of the equation is on the PhpStorm IDE end of things, provided by the Symfony Support plugin.

One of the things this PhpStorm plugin (written in Java) does is parse your code for Twig extensions that add global variables.

It’s important to note that it does not actually evaluate any PHP code. Instead, it parses all Twig extension PHP classes looking for a getGlobals() method that returns a key/value array via a return [] statement and makes their values available as global variables in Twig for autocompletion.

The reason this has never "just worked" in the history of Craft CMS up until version 3.7.8 is that Craft returned an array as a variable, rather than as a static key/value pair array, so the Symfony plugin could not parse it.

If a plugin or module (or even Craft pre 3.7.8) does not return a key/value array directly then autocompletion simply will not work (Andrew had to discover this by source-diving the Symfony Support plugin):

/**
 * @author Daniel Espendiller <[email protected]>
 */
public class GlobalExtensionVariableCollector implements TwigFileVariableCollector {
    @Override
    public void collectPsiVariables(@NotNull TwigFileVariableCollectorParameter parameter, @NotNull Map<String, PsiVariable> variables) {
        for(PhpClass phpClass : TwigUtil.getTwigExtensionClasses(parameter.getProject())) {
            if(!PhpUnitUtil.isPhpUnitTestFile(phpClass.getContainingFile())) {
                Method method = phpClass.findMethodByName("getGlobals");
                if(method != null) {
                    Collection<PhpReturn> phpReturns = PsiTreeUtil.findChildrenOfType(method, PhpReturn.class);
                    for(PhpReturn phpReturn: phpReturns) {
                        PhpPsiElement returnPsiElement = phpReturn.getFirstPsiChild();
                        if(returnPsiElement instanceof ArrayCreationExpression) {
                            variables.putAll(PhpMethodVariableResolveUtil.getTypesOnArrayHash((ArrayCreationExpression) returnPsiElement));
                        }
                    }
                }
            }
        }
    }
}

Once PhpStorm has indexed these two classes, autocompletion for Craft and all plugins and modules immediately becomes available in your Twig templates, just like magic!

Hat tip

Hat tip to Oliver Stark for his work on ostark/craft-prompter.


Brought to you by nystudio107 and PutYourLightsOn.

Comments
  • Craft Commerce auto-complete broken (again?)

    Craft Commerce auto-complete broken (again?)

    Describe the bug

    Similar to this issue: https://github.com/nystudio107/craft-autocomplete/issues/6

    craft.commerce craft.orders craft.products

    None are autocompleted or recognized.

    Versions

    • Plugin version: 1.10.1
    • Craft version: 4.2.7
    bug 
    opened by TomDeSmet 7
  • Add generator events

    Add generator events

    It would be helpful to have events in AutocompleteVariableGenerator and AutocompleteTwigExtensionGenerator that make it easy to add properties to AutocompleteVariable and globals to AutocompleteTwigExtension respectively.

    The usage would be as follows.

    use nystudio107\autocomplete\generators\AutocompleteVariableGenerator;
    use yii\base\Event;
    
    Event::on(AutocompleteVariableGenerator::class,
        AutocompleteVariableGenerator::EVENT_BEFORE_GENERATE,
        function(Event $event) {
            $event->data[MyClass::class] = 'myClass';
        }
    );
    
    use nystudio107\autocomplete\generators\AutocompleteTwigExtensionGenerator;
    use yii\base\Event;
    
    Event::on(AutocompleteTwigExtensionGenerator::class,
        AutocompleteTwigExtensionGenerator::EVENT_BEFORE_GENERATE,
        function(Event $event) {
            $event->data['myValue'] = 'hello';
        }
    );
    
    enhancement 
    opened by bencroker 7
  • PHPStorm still not picking up hints despite a correct-looking setup

    PHPStorm still not picking up hints despite a correct-looking setup

    Question

    I'm not sure what my PHPStorm install is getting wrong about my app, but it cannot resolve the hinted properties on the craft variable. I am using a Lando (Docker) local setup, and can confirm that PHPStorm has bound read/write access to the entire storage directory, including the compiled_classes directory.

    Additional context

    AutocompleteVariable.php Screenshot 2021-08-23 at 13 01 03

    craft variable is correctly showing as an instance of the AutocompleteVariable class Screenshot 2021-08-23 at 13 00 13

    But I cannot auto-complete imagerx, as an example Screenshot 2021-08-23 at 13 01 32

    I have cleared Craft's caches and temp files and regenerated the auto-complete classes. I have tried marking the complied_classes folder as a 'Source Root' in PHPStorm. I have not configured the Symfony plugin for this project beyond the defaults - does it need configuring? I have also tried clearing the Index in the Symfony plugin, invalidating all PHPStorm caches and rebooting.

    question 
    opened by roberttolton 7
  • Missing required parameter

    Missing required parameter "id" when instantiating

    I was trying to install craft-autocomplete in PhpStorm and ran into the following error:

    Missing required parameter "id" when instantiating "nystudio107\autocomplete\Autocomplete".

    Additional context

    Craft Solo 3.5.19.1
    PHP 7.4.21
    
    "require": {
      "craftcms/cms": "^3.0.1",
      "vlucas/phpdotenv": "^2.4.0",
      "focuslabllc/craft-cheat-sheet": "^2.0.3"
    },
    
    

    Output

    bash-3.2$ composer require nystudio107/craft-autocomplete --dev
    Using version ^1.10 for nystudio107/craft-autocomplete
    ./composer.json has been updated
    Running composer update nystudio107/craft-autocomplete
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 1 install, 0 updates, 0 removals
      - Locking nystudio107/craft-autocomplete (1.10.0)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 1 install, 0 updates, 0 removals
      - Installing nystudio107/craft-autocomplete (1.10.0): Extracting archive
    Generating optimized autoload files
    
    

    Error

    2022-03-02 14:02:24 [-][-][-][error][yii\base\InvalidConfigException] yii\base\InvalidConfigException: Missing required parameter "id" when instantiating "nystudio107\autocomplete\Autocomplete". in /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/di/Container.php:498
    Stack trace:
    #0 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/di/Container.php(393): yii\di\Container->resolveDependencies(Array, Object(ReflectionClass))
    #1 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/di/Container.php(165): yii\di\Container->build('nystudio107\\aut...', Array, Array)
    #2 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/BaseYii.php(345): yii\di\Container->get('nystudio107\\aut...', Array)
    #3 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/base/Application.php(294): yii\BaseYii::createObject('nystudio107\\aut...')
    #4 /Users/hartbr/websites/brianhartdesign-craft3/vendor/craftcms/cms/src/console/Application.php(61): yii\base\Application->bootstrap()
    #5 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/base/Application.php(273): craft\console\Application->bootstrap()
    #6 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/console/Application.php(124): yii\base\Application->init()
    #7 /Users/hartbr/websites/brianhartdesign-craft3/vendor/craftcms/cms/src/console/Application.php(47): yii\console\Application->init()
    #8 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/base/BaseObject.php(109): craft\console\Application->init()
    #9 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/base/Application.php(206): yii\base\BaseObject->__construct(Array)
    #10 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/console/Application.php(89): yii\base\Application->__construct(Array)
    #11 [internal function]: yii\console\Application->__construct(Array)
    #12 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/di/Container.php(406): ReflectionClass->newInstanceArgs(Array)
    #13 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/di/Container.php(165): yii\di\Container->build('craft\\console\\A...', Array, Array)
    #14 /Users/hartbr/websites/brianhartdesign-craft3/vendor/yiisoft/yii2/BaseYii.php(365): yii\di\Container->get('craft\\console\\A...', Array, Array)
    #15 /Users/hartbr/websites/brianhartdesign-craft3/vendor/craftcms/cms/bootstrap/bootstrap.php(246): yii\BaseYii::createObject(Array)
    #16 /Users/hartbr/websites/brianhartdesign-craft3/vendor/craftcms/cms/bootstrap/console.php(51): require('/Users/hartbr/w...')
    #17 /Users/hartbr/websites/brianhartdesign-craft3/craft(21): require('/Users/hartbr/w...')
    #18 {main}
    
    question 
    opened by hartless 5
  • Globals are not auto-completed

    Globals are not auto-completed

    Describe the bug

    Globals are not auto-completed

    To reproduce

    Steps to reproduce the behaviour:

    1. Create a global (e.g. 'website')
    2. Assign field to said global.
    3. Try to use the autocomplete functionality

    Expected behaviour

    The editor should auto-complete globals.

    Screenshots

    Other auto-completions do work: craft autocompletes entry autocompletes Global auto-completion doesn't work: global in craft global does not autocomplete

    Versions

    • Plugin version: 1.0.5
    • Craft version: 3.7.20
    bug 
    opened by mikesnoeren 4
  • WIP tests with pests

    WIP tests with pests

    I did "some changes" to the actual codebase to make it easier to test, mainly opinionated stuff.

    Please mind the change on the GeneratorInterface! static method calls are not static anymore.

    WIP Current state

    • So far I haven't installed it, it might be broken.
    • phpstan isn't happy so far
    • no focus on code formatting so far

    more notes here

    Missing tests

    • variables from plugins
    • exotic custom generators :-)
    opened by ostark 3
  • Uninstalling a plugin can cause an exception

    Uninstalling a plugin can cause an exception

    Uninstalling a plugin can cause Autocomplete to kick in and attempt to regenerate its files. Problem is, the Twig context will contain references to the stale globals.

    Instead, on plugin uninstall, we should just invalidate the caches and let them regenerate on the next request.

    Try uninstalling SEOmatic with Craft Autocomplete installed, and you'll see this bug.

    bug 
    opened by khalwat 2
  • Remove 10 second rule

    Remove 10 second rule

    @khalwat Craft generates the CustomFieldBehavior class only if the file already exists – the 10 second rule comes only later in the generation process. https://github.com/craftcms/cms/blob/96fc9a3f2fc7caabc44d12d786dea2a39ffa4b62/src/Craft.php#L183-L186

    opened by bencroker 1
  • Remove 10 second rule

    Remove 10 second rule

    @khalwat Craft generates the CustomFieldBehavior class only if the file already exists – the 10 second rule comes only later in the generation process. https://github.com/craftcms/cms/blob/96fc9a3f2fc7caabc44d12d786dea2a39ffa4b62/src/Craft.php#L183-L186

    opened by bencroker 0
Releases(1.11.0)
Owner
nystudio107
Consulting, Branding, Design, Development
nystudio107
Provides autocompletion for Craft CMS and plugins in Twig templates.

Autocomplete for Craft CMS Provides autocompletion for Craft CMS and plugins in Twig templates. Currently works with PhpStorm only, as VSCode does not

PutYourLightsOn 12 Nov 23, 2021
Returns a list of Craft/Vue/React route rules and element URLs for ServiceWorkers from Craft entries

Route Map plugin for Craft CMS 3.x Returns a list of Craft/Vue/React route rules and element URLs for ServiceWorkers from Craft entries Related: Route

nystudio107 30 Mar 14, 2022
Plugin Vite is the conduit between Craft CMS plugins and Vite, with manifest.json & HMR support

Plugin Vite Related Articles: Vite.js Next Generation Frontend Tooling + Craft CMS A Vite Buildchain for Craft CMS Plugins Requirements Craft CMS 3.0.

nystudio107 8 Dec 30, 2022
Plugin for Craft CMS that makes it easy to interact with the Instagram Basic Display API and Instagram oEmbed.

Instagram Basic Display plugin for Craft CMS 3.x This plugin creates endpoints in your Craft install for you to consume the Instagram Basic Display AP

Jonathan Melville 5 Dec 20, 2022
A plugin for Craft CMS 3.X that allows for GraphQL search functionality for matching on fields of nested entries.

Nested Entry GraphQL Plugin This Craft CMS plugin allows for performing graphQL search queries that match on fields on nested entries-as-a-field. What

Rubin EPO 2 Sep 10, 2021
Element Relations Plugin for Craft CMS 3.x

Element Relations Plugin for Craft CMS 3.x This plugin shows all relations of an element. For example, where an asset, entry or any other element is l

Frederic Köberl 2 Jul 18, 2022
Monet Plugin for Craft CMS

A Monet field can be added to asset elements which will generate and store an efficient placeholder image to be displayed inline, whilst the full asset is loading.

Chris Dyer 1 Jan 21, 2022
Make development easier with IDE helpers for Winter CMS!

IDE Helpers This plugin adds barryvdh/ide-helpers package to October for better IDE support. Installation git clone into /plugins/flynsarmy/idehelper

null 4 Dec 11, 2021
Craft is a flexible, user-friendly CMS for creating custom digital experiences on the web and beyond.

About Craft CMS Craft is a flexible, user-friendly CMS for creating custom digital experiences on the web and beyond. It features: An intuitive, user-

Craft CMS 2.9k Jan 1, 2023
Allows the use of the Vite.js next generation frontend tooling with Craft CMS

Vite plugin for Craft CMS 3.x Allows the use of the Vite.js next generation frontend tooling with Craft CMS Related Article: Vite.js Next Generation F

nystudio107 38 Dec 30, 2022
A BlurHash implementation for Craft CMS.

BlurHash plugin for Craft CMS 3.x Render a BlurHash from a given asset in Craft CMS. A BlurHash is a compact representation of a placeholder for an im

Dodeca Studio 8 Nov 12, 2022
Edit richt text content in Craft CMS using Article by Imperavi.

Article Editor About the plugin This plugin brings the powerful Article Editor from Imperavi to Craft CMS, allowing you to make create beautiful rich

Creativeorange 6 Mar 30, 2022
Create WordPress themes with beautiful OOP code and the Twig Template Engine

Timber helps you create fully-customized WordPress themes faster with more sustainable code. With Timber, you write your HTML using the Twig Template Engine separate from your PHP files.

Timber 5.2k Dec 31, 2022
Bismuth CMS is a ready-made Website CMS based on Yii 2 Advance Template

Bismuth CMS is a ready-made Website CMS based on Yii 2 Advance Template, it's the simplest and easy to set up CMS you may come across.

Hamadas Telebrain 1 Feb 11, 2022
True Multisite, Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony

True Multisite, Modern, Crazy Fast, Ridiculously Easy and Amazingly Powerful Flat-File CMS powered by PHP, Markdown, Twig, and Symfony

null 4 Oct 28, 2022
A template package of package development for Concrete CMS Version 9.

A boilerplate to develop a package on Concrete CMS Version 9.

株式会社マカルーデジタル 11 Nov 27, 2022
Botble plugin comment is a comment plugin for Botble CMS

Botble plugin comment This is a plugin for Botble CMS so you have to purchase Botble CMS first to use this plugin.

Bảo Bối 27 Nov 25, 2021
Flextype is an open-source Hybrid Content Management System with the freedom of a headless CMS and with the full functionality of a traditional CMS

Flextype is an open-source Hybrid Content Management System with the freedom of a headless CMS and with the full functionality of a traditional CMS. Building this Content Management System, we focused on simplicity. To achieve this, we implemented a simple but powerful API's.

Flextype 524 Dec 30, 2022
PHPVibe Open source video CMS / Video Sharing CMS / Youtube Api v3 / Video Embeds

PHPVibe Video CMS Free Video Sharing CMS The modern choice of design inspired by Youtube and a social videos sharing module that may just cut it for y

MediaVibe 71 Dec 18, 2022