nystudio107 / craft-autocomplete
提供Craft CMS及插件变量的Twig模板IDE自动完成
Requires
- craftcms/cms: ^3.0.0 || ^4.0.0 || ^5.0.0
Requires (Dev)
- craftcms/ecs: dev-main
- craftcms/phpstan: dev-main
- craftcms/rector: dev-main
README
为Craft CMS 3.x, 4.x & 5.x提供自动完成
提供Craft CMS和插件/模块变量及元素类型的Twig模板IDE自动完成。
如果已安装Symfony支持插件,则与PhpStorm一起使用。VSCode目前不支持Twig扩展的智能提示。
虽然Craft 3.7.8版本增加了Craft的全局Twig变量自动完成,但这不包括插件和模块提供的变量或元素类型的自动完成。
要求
此包需要Craft CMS 3.x, 4.x或5.x
使用方法
- 使用composer安装包,将其添加到
require-dev
composer require nystudio107/craft-autocomplete --dev
-
确保已安装并启用了PhpStorm的Symfony支持插件,通过检查Symfony插件设置中的“为项目启用”复选框来完成。
-
确保
devMode
已启用。 -
访问安装了包的Craft网站以在
storage/runtime/compiled_classes/
中生成自动完成类,或运行以下控制台命令。
php craft autocomplete/generate
一旦您的IDE索引了自动完成类,Craft以及所有插件和模块的自动完成功能将立即在您的Twig模板中可用。
此外,Craft和插件/模块提供的元素类型的自动完成也可用,例如:asset
、entry
、category
、tag
、user
、product
(如果已安装Craft Commerce)等。
注意:如果您使用的是Docker配置,请确保storage/runtime/compiled_classes/
绑定在您的客户端机器上,以便您的IDE可以找到类以进行索引。
重新生成自动完成类
如果它们尚不存在,则在Craft执行(无论是通过前端请求还是通过CLI)时,将生成所有自动完成类。
每次您安装或卸载插件时,都会重新生成所有自动完成类。
如果您手动添加了一个在Craft全局变量上注册变量的插件或模块,可以通过运行以下控制台命令强制重新生成自动完成类。
php craft autocomplete/regenerate
...或者,由于自动完成类在不存在时自动重新生成,您可以通过以下方式清除运行时缓存:
php craft clear-caches/temp-files
扩展
您可以使用EVENT_BEFORE_GENERATE
事件来扩展Generator
类添加的值。
use nystudio107\autocomplete\events\DefineGeneratorValuesEvent; use nystudio107\autocomplete\generators\AutocompleteTwigExtensionGenerator; use yii\base\Event; Event::on(AutocompleteTwigExtensionGenerator::class, AutocompleteTwigExtensionGenerator::EVENT_BEFORE_GENERATE, function(DefineGeneratorValuesEvent $event) { $event->values['myVariable'] = 'value'; } );
除了提供的自动完成生成器类型外,您还可以通过实现GeneratorInterface
类或扩展抽象的Generator
类(推荐)来编写自己的。
<?php namespace vendor\package; use nystudio107\autocomplete\base\Generator; class MyAutocompleteGenerator extends Generator { // Override base methods }
要注册您的生成器类型,请监听EVENT_REGISTER_AUTOCOMPLETE_GENERATORS
事件并将您的类添加到types
属性。
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; } );
请参阅包含的生成器以了解如何创建自己的。
工作原理
在PhpStorm IDE中进行自动完成的征途中,Andrew多年前撰写了一篇题为使用PhpStorm在Twig中自动完成Craft CMS 3 APIs的文章。
这与Craft自动完成的工作原理类似,但它是一个手动过程。
Ben和Andrew认为他们可以做得更好。
引导Yii2扩展
这个包是一个Yii2扩展(也是一个模块),它可以自我引导。
这意味着它会自动与Craft一起加载,而无需您安装或以任何方式配置它。
只有当devMode
启用时,它才会执行任何操作,因此您可以将其安装在生产环境中。
生成的自动完成类
Craft自动完成所做的只是生成源代码文件,这与Craft本身在storage/runtime/compiled_classes
中生成一个CustomFieldBehavior类的方式非常相似
然而,Craft自动完成生成的代码永远不会运行。它只存在以允许您的IDE对其进行索引以实现自动完成。
在引导过程中,如果这两个类AutocompleteTwigExtension
和AutocompleteVariable
不存在,或者安装或卸载了Craft插件,则该包会生成这两个类。
AutocompleteTwigExtension
类通过评估已注册的所有Twig全局变量来生成。通过动态评估全局Craft变量(包括通过插件和模块注册的任何变量),生成AutocompleteVariable
类。
以下是一个示例,说明它生成的文件可能的样子,存储在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(), ]; } }
PhpStorm的Symfony支持插件
方程式的另一半在PhpStorm IDE端,由Symfony支持插件提供。
此PhpStorm插件(用Java编写)所做的其中一件事是解析您的代码以查找添加全局变量的Twig扩展。
需要注意的是,它实际上并没有评估任何PHP代码。相反,它解析所有Twig扩展PHP类,寻找返回键/值数组的getGlobals()
方法,并通过return []
语句使其值在Twig中作为全局变量可用于自动完成。
这之所以在Craft CMS的历史上从未“自动”工作,是因为直到版本3.7.8之前,Craft返回了一个变量作为数组,而不是作为静态键/值对数组,因此Symfony插件无法解析它。
如果插件或模块(甚至Craft 3.7.8之前的Craft)没有直接返回键/值数组,则自动完成将无法工作(Andrew必须通过源代码挖掘Symfony支持插件来发现这一点)
/** * @author Daniel Espendiller <daniel@espendiller.net> */ 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)); } } } } } } }
一旦PhpStorm对这些两个类进行了索引,Craft及其所有插件和模块的自动完成就会立即在您的Twig模板中可用,就像魔法一样!
致谢
感谢Oliver Stark为他的工作ostark/craft-prompter做出贡献。