Does PHPStorm not support code folding for Twig?
I rely on code folding heavily to write code; I use it to remove things from my sight that are not relevant to the issue I'm working on - it helps remove distraction. I am finding that working with Twig in PHPStorm is far from optimal because I can't fold Twig properly.
For example, in the following code block I want to fold: The case block. The macro call. The form open tag.


In comparison with this same code, VSCode gets all this folding correct:



请先登录再写评论。
Could you please share the code samples as text? I'll extract each case as a feature request, but there's no fun in re-typing code from a screenshot. Thank you!
Of course, no problem. Here's the complete twig file:
{% import '_macros' as macros %}
{% if sprig.isRequest %}
{% set form = wheelform.form({
id: formId
}) %}
{% if success %}
{% if formRedirect is defined and formRedirect | length %}
<script>
location.assign("{{ formRedirect }}");
</script>
{% endif %}
<p class="message success">
{{ wheelform.settings.success_message }}
</p>
{% else %}
<form
sprig
s-method="post"
s-encoding="multipart/form-data"
s-action="wheelform/message/send"
>
<input type="hidden" name="form_id" value="{{ formId }}">
{% if formRedirect | length %}
<input type="hidden" name="redirect" value="{{ formRedirect }}">
{% endif %}
{{ wheelformErrors['form'] is defined ? macros.errorList(wheelformErrors['form']) }}
{{ wheelformErrors['recaptcha'] is defined ? macros.errorList(wheelformErrors['recaptcha']) }}
{{ wheelformErrors['honeypot'] is defined ? macros.errorList(wheelformErrors['honeypot']) }}
{% for field in form.fields %}
{% switch field.type %}
{% case 'hidden' %}
<input
type="hidden"
name="{{field.name}}"
value="{{ item }}"
/>
{% case "radio" %}
{# Build the radio buttons array... #}
{% set options = [] %}
{% for item in field.items %}
{% set options = options | merge( [{
type : field.type,
label : item,
value : item,
name : field.name,
id : field.name ~ loop.index ~ formId,
checked : values[field.name] is defined and item == values[field.name]
}] ) %}
{% endfor %}
{% set groupError = null %}
{% if wheelformErrors is defined and wheelformErrors[field.name] %}
{% set groupError = wheelformErrors[field.name][0] %}
{% endif %}
{{ macros.htmlRadioset({
legend : field.options.display_label ? field.label ??? null,
legendStyle: 'dc_uppercase-adjusted',
required : field.required,
error : groupError,
options : options
}) }}
{% case "checkbox" %}
{# Build the radio buttons array... #}
{% set options = [] %}
{% for item in field.items %}
{% set options = options | merge( [{
type : field.type,
label : item,
value : item,
name : field.name ~ '[]',
id : field.name ~ loop.index ~ formId,
checked : values[field.name] is defined and item == values[field.name]
}] ) %}
{% endfor %}
{% set groupError = null %}
{% if wheelformErrors is defined and wheelformErrors[field.name] %}
{% set groupError = wheelformErrors[field.name][0] %}
{% endif %}
{{ macros.htmlRadioset({
legend : field.options.display_label ? field.label ??? null,
legendStyle: 'dc_uppercase-adjusted',
required : field.required,
error : groupError,
options : options
}) }}
{% case "select" %}
{% set options = [] %}
{% for item in field.items %}
{% set options = options | merge([
{
label: item,
value: item,
selected: values[field.name] is defined and item == values[field.name]
}
]) %}
{% endfor %}
{{ macros.htmlField({
type : 'select',
id : field.name ~ loop.index ~ formId,
name : field.name,
label : field.label ??? 'Field Label Not Set',
options: options,
error : wheelformErrors[field.name] is defined ? wheelformErrors[field.name][0] : null
}) }}
{% case "textarea" %}
{{ macros.htmlField({
type : 'textarea',
id : field.name ~ loop.index ~ formId,
name : field.name,
value : (values is defined ? values[field.name] : ''),
required : field.required,
label : field.label ??? 'Field Label Not Set',
instructions: null,
error : wheelformErrors[field.name] is defined ? wheelformErrors[field.name][0] : null
}) }}
{% case "file" %}
{{ macros.htmlField({
type : 'file',
id : field.name ~ loop.index ~ formId,
name : field.name,
value : (values is defined ? values[field.name] : ''),
required : field.required,
label : field.label ??? 'Field Label Not Set',
instructions: null,
error : wheelformErrors[field.name] is defined ? wheelformErrors[field.name][0] : null
}) }}
<script>
var uploadField = document.getElementById("{{ field.name ~ loop.index ~ formId }}");
uploadField.onchange = function() {
if(this.files[0].size > 8388608){
alert("Sorry, the file size you are trying to upload is too big, please reduce the file size. ");
this.value = "";
};
};
</script>
{% case "html" %}
<div class="wheelform-html">
{{ field.content | raw }}
</div>
{% default %}
{{ macros.htmlField({
type : 'text',
id : field.name ~ loop.index ~ formId,
name : field.name,
value : (values is defined ? values[field.name] : ''),
required : field.required,
label : field.label ??? 'Field Label Not Set',
instructions: null,
error : wheelformErrors[field.name] is defined ? wheelformErrors[field.name][0] : null
}) }}
{% endswitch %}
{% endfor %}
{% if form.recaptcha %}
<div>
<script src="https://www.google.com/recaptcha/api.js"></script>
<!-- Production captcha -->
<div class="g-recaptcha" data-sitekey="{{ wheelform.getSettings('recaptcha_public') }}"></div>
</div>
{% endif %}
<div class="formActions">
<div class="message">* Required fields</div>
<button class="dc_button">Send Message</button>
</div>
</form>
{% endif %}
{% else %}
<p>Fetching form...</p>
{% endif %}
Thank you! I've extracted the switch case request:
https://youtrack.jetbrains.com/issue/WI-67995/Twig-Ability-to-fold-switch-case-blocks
Folding tag attributes isn't even supported in HTML; here's a feature request for that:
https://youtrack.jetbrains.com/issue/WEB-31463/Add-code-folding-for-wrapped-attributes-in-HTMLXML-tags-collapse-attributes
Do I get it right that when you say "macro call", you actually mean that you want to fold the hash you pass as an argument?
https://twig.symfony.com/doc/3.x/templates.html#literals
Great stuff, thank you.
I mean this block here:
{{ macros.htmlField({type : 'text',
id : field.name ~ loop.index ~ formId,
name : field.name,
value : (values is defined ? values[field.name] : ''),
required : field.required,
label : field.label ??? 'Field Label Not Set',
instructions: null,
error : wheelformErrors[field.name] is defined ? wheelformErrors[field.name][0] : null
}) }}
so ideally it'd fold to
{{ macros.htmlField({}) }}
Which is what VSCode does.
Yep, it's a hash that has to be collapsed then. It makes sense to support it for arrays too.
Extracted: https://youtrack.jetbrains.com/issue/WI-68018/Twig-Folding-of-multiline-hashes-and-arrays