Learn more about Sticky Posts */ public bool $isIgnoreStickyPosts; /** * @label Without Web Component * @instructions By default, every Card 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 Use the Post ID as the Card 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 textarea * @label Query Preview * @instructions For debug purposes. Here you can see the query that will be executed to get posts for this card. Important! Publish or Update your card and reload the page to see the latest query */ public string $queryPreview; /** * @a-type textarea * @label Custom Data * @instructions Using this field you can add extra variables to the template and extra arguments the WP_Query instance.
The data return must be an associative array, where keys are names. Read more
Press Ctrl (Cmd) + Alt + L to format the code. Press Ctrl + F to search (or replace). * @a-pro The field must be not required or have default value! */ public string $extraQueryArguments; /** * @a-type tab * @label Template */ public bool $templateTab; /** * @a-type textarea * @new_lines br * @label Default Template * @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, such as adding an extra heading.

Powerful Twig features, including our functions, are available for you.

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

Make sure you've retained all the default classes; otherwise, pagination won't work. */ 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-card'). */ 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 tab * @label CSS & JS */ public bool $cssAndJsTab; /** * @a-type textarea * @label CSS Code * @instructions Define your CSS style rules.
This will be added within <style></style> tags ONLY to pages that have this card.

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

Don't style view fields here, View has its own CSS field for this goal.

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

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

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

'#__' will be replaced with '.acf-card__' (or '.bem-name__').

To match items wrapper you should use '#card__items' selector, to match single item you should use '#card .acf-view' selector * / */ public string $cssCode; /** * @a-type textarea * @label JS Code * @instructions Add your custom Javascript to your Card.

By default, the Card 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 Card 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 Layout */ public bool $layoutTab; /** * @a-type select * @label Enable Slider * @instructions Select the slider library to enable.
Customize the slider after saving, by editing the JS Code in the CSS & JS tab * @choices {"none":"None","splide_v4":"Splide v4 (29.8KB js, 5KB css)"} * @default_value none * @a-pro The field must be not required or have default value! */ public string $sliderType; /** * @label Enable Layout rules * @instructions When enabled CSS layout styles are added to CSS Code in the Advanced tab. These styles are automatically updated each time.
Tip: If you’d like to edit the Layout CSS manually, simply disable this here. Disabling this does not remove the previously added CSS Code */ public bool $isUseLayoutCss; /** * @var CardLayoutData[] * @item \org\wplake\advanced_views\Groups\CardLayoutData * @label Layout Rules * @instructions The rules control layout of card items.
Note: These rules are inherited from small to large. For example: If you’ve set up 'Mobile' and 'Desktop' screen rules, then 'Tablet' will have the same rules as 'Mobile' and 'Large Desktop' will have the same rules as 'Desktop' * @button_label Add Rule * @a-no-tab 1 */ public array $layoutRules; /** * @a-type tab * @label Meta Filters * @a-pro 1 */ public bool $metaFiltersTab; /** * @a-no-tab 1 * @display seamless */ public MetaFilterData $metaFilter; /** * @a-type tab * @label Taxonomy Filters * @a-pro 1 */ public bool $taxFiltersTab; /** * @label Rules * @a-no-tab 1 * @display seamless */ public TaxFilterData $taxFilter; /** * @a-type tab * @label Pagination * @a-pro 1 */ public bool $paginationTab; /** * @label With Pagination * @instructions If enabled then instead of displaying all posts from query results, only the limited number of posts will be shown and user will be able to load more. Read more * @a-pro The field must be not required or have default value! */ public bool $isWithPagination; /** * @a-type select * @required 1 * @label Pagination Type * @instructions Defines a way in which user can load more. For 'Load More Button' and 'Page Numbers' cases a special markup will be added to the card automatically, you can style it (using the 'CSS Code' field in the 'Advanced' tab) * @choices {"load_more_button":"Load More Button","infinity_scroll":"Infinity Scroll","page_numbers":"Page Numbers"} * @default_value load_more_button * @a-pro The field must be not required or have default value! */ public string $paginationType; /** * @label Label for the 'Load More' button * @required 1 * @default_value Load more * @conditional_logic [[{"field": "local_acf_views_acf-card-data__pagination-type","operator": "==","value": "load_more_button"}]] * @a-pro The field must be not required or have default value! */ public string $loadMoreButtonLabel; /** * @label Posts Per Page * @instructions Controls how many posts will be displayed initially and how many posts will be appended every time when user triggers 'Load More'. Total amount of post is limited by the 'Maximum amount of posts' field in the 'Filter' tab * @required 1 * @default_value 9 * @a-pro The field must be not required or have default value! */ public int $paginationPerPage; /** * @a-type tab * @label Preview */ public bool $previewTab; /** * @label Preview * @instructions See an output preview of your Card, where you can test some CSS styles. Read more
Styles from your front page are included in the preview (some differences may appear).
Note: Press 'Update' if you have changed Custom Markup (in the Advanced tab) to see the latest preview.
Important! Don't style your View here, instead use the CSS Code field in your View for this goal.
After testing: Copy and paste the Card styles to the CSS Code field. * @placeholder Loading... Please wait a few seconds * @disabled 1 */ public string $preview; // cache private string $noPostsFoundMessageTranslation; private string $loadMoreButtonLabelTranslation; public function __construct(CreatorInterface $creator) { parent::__construct($creator); $this->noPostsFoundMessageTranslation = ''; $this->loadMoreButtonLabelTranslation = ''; } protected static function getFieldInfo(string $fieldName): ?FieldInfoInterface { $fieldInfo = parent::getFieldInfo($fieldName); if (null === $fieldInfo) { return null; } switch ($fieldInfo->getName()) { case self::FIELD_EXTRA_QUERY_ARGUMENTS: $fieldInfo->setArgument( 'default_value', // do not add 'PHP' to avoid issue with security plugins like WordFence ' declare(strict_types=1); use org\wplake\advanced_views\pro\Cards\CustomCardData; return new class extends CustomCardData { /** * @return array */ public function getVariables(): array { return [ // "another_var" => $this->customArguments["another"] ?? "", ]; } /** * @return array */ public function getVariablesForValidation(): array { // it\'s better to return dummy data here [ "another_var" => "dummy string", ] return $this->getVariables(); } public function getQueryArguments(): array { // https://developer.wordpress.org/reference/classes/wp_query/#parameters return [ // "author" => get_current_user_id(), // "post_parent" => $this->customArguments["post_parent"] ?? 0, ]; } }; ' ); break; } return $fieldInfo; } /** * @return array * @throws Exception */ public static function getGroupInfo(): array { return array_merge(parent::getGroupInfo(), [ 'title' => __('Card settings', 'acf-views'), ]); } /** * @return string[] */ protected function getUsedMetaGroupIds(): array { return [$this->acfViewId,]; } /** * @return array */ protected function getMultilingualStringsFromLabels(): array { $labels = []; if ('' !== $this->noPostsFoundMessage) { $labels[] = $this->noPostsFoundMessage; } if ('' !== $this->loadMoreButtonLabel) { $labels[] = $this->loadMoreButtonLabel; } return [] !== $labels ? [ Plugin::getThemeTextDomain() => $labels, ] : []; } 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 ? $this->bemName : 'acf-card--id--' . $markupId; // magic shortcuts $cssCode = str_replace( '#card__', sprintf('.%s .%s__', $selector, $this->getBemName()), $cssCode ); $cssCode = str_replace( '#card', sprintf('.%s', $selector), $cssCode ); $cssCode = str_replace( '#__', sprintf('.%s__', $this->getBemName()), $cssCode ); } elseif ($isPreview) { $cssCode = str_replace('#card__', sprintf('#card .%s__', $this->getBemName()), $cssCode); } // back the right way, as before it was hack for CodeMirror $cssCode = str_replace('"1fr"', '1fr', $cssCode); $cssCode = trim($cssCode); return $cssCode; } /** * @return array */ public function getMultilingualStrings(): array { $mlStrings = $this->getMultilingualStringsFromLabels(); $customMarkup = trim($this->customMarkup); if ('' !== $customMarkup) { $mlStrings = $this->getMultilingualStringsFromCustomMarkup($mlStrings); } return $mlStrings; } public function getOrderByMetaAcfFieldId(): string { return FieldData::getFieldIdByKey($this->orderByMetaFieldKey); } public function getOrderByMetaFieldSource(): string { return FieldData::getVendorNameByKey($this->orderByMetaFieldKey); } public function getBemName(): string { $bemName = trim($this->bemName); if ('' === $bemName) { return 'acf-card'; } $bemName = preg_replace('/[^a-z0-9\-_]/', '', $bemName); return null != $bemName ? $bemName : 'acf-card'; } public function getNoPostsFoundMessageTranslation(): string { if ('' !== $this->noPostsFoundMessage && '' === $this->noPostsFoundMessageTranslation) { $this->noPostsFoundMessageTranslation = Plugin::getLabelTranslation($this->noPostsFoundMessage); } return $this->noPostsFoundMessageTranslation; } public function getLoadMoreButtonLabelTranslation(): string { if ('' !== $this->loadMoreButtonLabel && '' === $this->loadMoreButtonLabelTranslation) { $this->loadMoreButtonLabelTranslation = Plugin::getLabelTranslation($this->loadMoreButtonLabel); } return $this->loadMoreButtonLabelTranslation; } public function getTagName(string $prefix = ''): string { return parent::getTagName('acf-card'); } }