Tip : hover mouse on the field number column and drag to reorder * @button_label Add Field * @collapsed local_acf_views_field__key * @a-no-tab 1 */ public array $items; /** * @a-type tab * @label Template */ public bool $templateTab; /** * @a-type textarea * @new_lines br * @label Template Preview * @instructions Output preview of the generated Twig template.
Important! Publish or Update your view to see the latest markup. * @disabled 1 */ public string $markup; /** * @a-type textarea * @label Custom Template * @instructions Write your own template with full control over the HTML markup.
You can copy the Template Preview field output and make your changes.

Powerful Twig features, including our functions, are available for you.
Note: WordPress shortcodes inside the template are only supported in the Pro version.

Press Ctrl (Cmd) + Alt + L to format the code. Press Ctrl + F to search (or replace).

Important! This field will not be updated automatically when you add or remove fields, so you have to update this field manually to reflect the new changes (you can refer to the Template Preview field for assistance). Read more */ public string $customMarkup; /** * @label BEM Unique Name * @instructions Define a unique BEM name for the element that will be used in the markup, or leave it empty to use the default ('acf-view'). */ public string $bemName; /** * @label CSS classes * @instructions Add a class name without a dot (e.g. “class-name”) or multiple classes with single space as a delimiter (e.g. “class-name1 class-name2”).
These classes are added to the wrapping HTML element. Learn more about CSS Classes */ public string $cssClasses; /** * @a-type true_false * @label Add classification classes to the markup * @instructions By default, the field name is added as a prefix to all inner classes. For example, the image within the 'avatar' field will have the '__avatar-image' class.
Enabling this setting adds the generic class as well, such as '__image'. This feature can be useful if you want to apply styles based on field types. */ public bool $isWithCommonClasses; /** * @a-type true_false * @label Do not skip unused wrappers * @instructions By default, empty wrappers in the markup are skipped to optimize the output. For example, the '__row' wrapper will be skipped if there is no field label.
Enable this feature if you need all the wrappers in the output. */ public bool $isWithUnnecessaryWrappers; /** * @a-type textarea * @label Custom Template Variables * @instructions Add custom variables to the template using this PHP code snippet.
The snippet must return an associative array of values, where keys are variable names. Names should be PHP compatible, which means only letters and underscores are allowed.
You can access these variables in the template just like others: '{{ your_variable }}'.
Press Ctrl (Cmd) + Alt + L to format the code. Press Ctrl + F to search (or replace).
In the snippet, the following variables are predefined: '$_objectId' (current data post), '$_viewId' (current view id),'$_fields' (an associative field values array, where keys are field identifiers). Read more * @default_value Rules defined here will be added within <style></style> tags ONLY to pages that have this view.

Press Ctrl (Cmd) + Alt + L to format the code. Press Ctrl + F to search (or replace).

Magic shortcuts are available (and will use the BEM Unique Name if defined) :

'#view' will be replaced with '.acf-view--id--X' (or '.bem-name').

'#view__' will be replaced with '.acf-view--id--X .acf-view__' (or '.bem-name .bem-name__'). It means you can use '#view__row' and it'll be replaced with '.bem-name .bem-name__row'.

'#__' will be replaced with '.acf-view__' (or '.bem-name__') */ public string $cssCode; /** * @a-type textarea * @label JS Code * @instructions Add your custom Javascript to your View.

By default, the View is a web component, so this code will be executed once for every instance, and 'this', that refers to the current instance, is available.

The code snippet will be added within <script></script> tags ONLY to pages that have this View and also will be wrapped into an anonymous function to avoid name conflicts.

Press Ctrl (Cmd) + Alt + L to format the code. Press Ctrl + F to search (or replace).
Don't use inline comments ('//') inside the code, otherwise it'll break the snippet. */ public string $jsCode; /** * @a-type tab * @label Options */ public bool $optionsTab; /** * @a-type textarea * @label Description * @instructions Add a short description for your views’ purpose.
Note : This description is only seen on the admin Advanced Views list */ public string $description; /** * @label With Gutenberg Block * @instructions If checked, a separate gutenberg block for this view will be available. Read more * @a-pro The field must be not required or have default value! * @a-acf-pro ACF PRO version is necessary for this feature */ public bool $isHasGutenbergBlock; /** * @label Without Web Component * @instructions By default, every View is a web component, which allows you to work easily with the element in the JS code field */ public bool $isWithoutWebComponent; /** * @a-type true_false * @label Render template when it's empty * @instructions By default, if all the selected fields are empty, the Twig template won't be rendered.
Enable this option if you have specific logic inside the template and you want to render it even when all the fields are empty. */ public bool $isRenderWhenEmpty; /** * @a-type true_false * @label Use the Post ID as the View ID in the markup * @instructions Note: For backward compatibility purposes only. Enable this option if you have external CSS selectors that rely on outdated digital IDs */ public bool $isMarkupWithDigitalId; /** * @a-type true_false * @label Use the Post ID in the Gutenberg block's name * @instructions Note: For backward compatibility purposes only. * @a-deprecated IT'S INVISIBLE FIELD FOR BACK COMPATIBILITY ONLY */ public bool $isGutenbergBlockWithDigitalId; /** * @a-type tab * @label Preview */ public bool $previewTab; /** * @a-type post_object * @return_format 1 * @allow_null 1 * @label Preview Object * @instructions Select a data object (which field values will be used) and update the View. After reload the page to see the markup in the preview */ public int $previewPost; /** * @label Preview * @instructions Here you can see the preview of the view and play with CSS rules. Read more
Important! Update the View after changes and reload the page to see the latest markup here.
Your changes to the preview won't be applied to the view automatically, if you want to keep them copy amended CSS to the 'CSS Code' field and press the 'Update' button.
Note: styles from your front page are included in the preview (some differences may appear) * @placeholder Loading... Please wait a few seconds * @disabled 1 */ public string $preview; public static function getGroupInfo(): array { return array_merge(parent::getGroupInfo(), [ 'title' => __('View settings', 'acf-views'), ]); } protected function getUsedItems(): array { $fieldGroups = []; foreach ($this->items as $item) { $fieldGroup = explode('|', $item->field->key)[0]; // ignore 'magic' groups if (0 !== strpos($fieldGroup, '$')) { $fieldGroups[] = $fieldGroup; } foreach ($item->repeaterFields as $repeaterField) { $subFieldGroup = explode('|', $repeaterField->key)[0]; // ignore 'magic' groups if (0 !== strpos($subFieldGroup, '$')) { $fieldGroups[] = $subFieldGroup; } } } $fieldGroups = array_unique($fieldGroups); return $fieldGroups; } public function getCssCode(bool $isMinify = true, bool $isPreview = false): string { $cssCode = $this->cssCode; if ($isMinify) { $cssCode = $this->getMinifiedCss(); $markupId = $this->getMarkupId(); // do not use getBemName(), because it'll always return something $selector = $this->bemName ?: 'acf-view--id--' . $markupId; // magic shortcuts $cssCode = str_replace( '#view__', sprintf('.%s .%s__', $selector, $this->getBemName()), $cssCode ); $cssCode = str_replace( '#view', sprintf('.%s', $selector), $cssCode ); $cssCode = str_replace( '#__', sprintf('.%s__', $this->getBemName()), $cssCode ); $cssCode = trim($cssCode); } elseif ($isPreview) { $cssCode = str_replace('#view__', sprintf('#view .%s__', $this->getBemName()), $cssCode); } return $cssCode; } public function saveToPostContent(array $postFields = [], bool $isSkipDefaults = false): bool { $isHasGutenberg = $this->isHasGutenbergBlock ? static::POST_VALUE_IS_HAS_GUTENBERG : ''; $postFields = array_merge($postFields, [ static::POST_FIELD_IS_HAS_GUTENBERG => $isHasGutenberg, ]); return parent::saveToPostContent($postFields, $isSkipDefaults); } public function getBemName(): string { $bemName = trim($this->bemName); if (!$bemName) { return 'acf-view'; } return preg_replace('/[^a-z0-9\-_]/', '', $bemName); } public function getItemClass(string $suffix, FieldData $fieldData): string { $classes = []; $classes[] = $this->getBemName() . '__' . $fieldData->id . '-' . $suffix; if ($this->isWithCommonClasses) { $classes[] = $this->getBemName() . '__' . $suffix; } return implode(' ', $classes); } public function getTagName(string $prefix = ''): string { return parent::getTagName('acf-view'); } /** * @return FieldData[] */ public function getFieldsByType(string $type, bool $isGroupByLevel = false): array { $fitFields = []; $fitSubFields = []; foreach ($this->items as $item) { foreach ($item->repeaterFields as $repeaterField) { $isFit = $type === $repeaterField->getFieldMeta()->getType(); if (!$isFit) { continue; } $fitSubFields[] = $repeaterField; } $isFit = $type === $item->field->getFieldMeta()->getType(); if (!$isFit) { continue; } $fitFields[] = $item->field; } $allFields = array_merge($fitFields, $fitSubFields); return !$isGroupByLevel ? $allFields : [ 'fields' => $fitFields, 'subFields' => $fitSubFields, 'all' => $allFields, ]; } public function getItemSelector( FieldData $field, string $target, bool $isInnerTarget = false, bool $isSkipView = false ): string { $markupId = $this->getMarkupId(); $selector = ''; if (!$isSkipView) { $selector .= $this->bemName ? '.' . $this->bemName : sprintf( '.%s--id--%s', $this->getBemName(), $markupId ); $selector .= ' '; } $selector .= sprintf( '.%s__%s', esc_html($this->getBemName()), esc_html($field->id) ); // target can be empty, in case we need the field itself if ((!$this->isWithUnnecessaryWrappers && !$field->label && !$isInnerTarget) || !$target) { return $selector; } $selector = $this->isWithCommonClasses ? sprintf( '%s .%s__%s', esc_html($selector), esc_html($this->getBemName()), $target ) : sprintf( '%s .%s__%s-%s', esc_html($selector), esc_html($this->getBemName()), $field->id, $target ); return $selector; } }