nystudio107/craft-autocomplete

提供Craft CMS及插件变量的Twig模板IDE自动完成

支持包维护!
khalwat

安装量: 106 706

依赖: 5

建议者: 0

安全: 0

星级: 42

关注者: 5

分支: 3

开放问题: 0

类型:yii2-extension

1.12.1 2024-04-15 16:14 UTC

This package is auto-updated.

Last update: 2024-09-15 17:10:30 UTC


README

Scrutinizer Code Quality Code Coverage Build Status Code Intelligence Status

为Craft CMS 3.x, 4.x & 5.x提供自动完成

提供Craft CMS和插件/模块变量及元素类型的Twig模板IDE自动完成。

如果已安装Symfony支持插件,则与PhpStorm一起使用。VSCode目前不支持Twig扩展的智能提示。

虽然Craft 3.7.8版本增加了Craft的全局Twig变量自动完成,但这不包括插件和模块提供的变量或元素类型的自动完成。

demo

要求

此包需要Craft CMS 3.x, 4.x或5.x

使用方法

  1. 使用composer安装包,将其添加到require-dev
composer require nystudio107/craft-autocomplete --dev
  1. 确保已安装并启用了PhpStorm的Symfony支持插件,通过检查Symfony插件设置中的“为项目启用”复选框来完成。

  2. 确保devMode已启用。

  3. 访问安装了包的Craft网站以在storage/runtime/compiled_classes/中生成自动完成类,或运行以下控制台命令。

php craft autocomplete/generate

一旦您的IDE索引了自动完成类,Craft以及所有插件和模块的自动完成功能将立即在您的Twig模板中可用。

screenshot

此外,Craft和插件/模块提供的元素类型的自动完成也可用,例如:assetentrycategorytaguserproduct(如果已安装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对其进行索引以实现自动完成。

在引导过程中,如果这两个类AutocompleteTwigExtensionAutocompleteVariable不存在,或者安装或卸载了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做出贡献。

nystudio107PutYourLightsOn提供。