cache = Cache::for('feed_block', WEEK_IN_SECONDS); // if (JVB_TESTING) { // $this->cache->flush(); // } add_action('init', [$this, 'registerBlock']); } public function registerBlock() { register_block_type($this->path, [ 'render_callback' => [$this, 'render'] ]); } protected function buildParams(array $attributes): array { if (!jvbCheck('inheritQuery', $attributes)) { return [ 'title' => $attributes['title'], 'content' => $attributes['contentTypes'], 'taxonomies' => $this->getTaxonomies($attributes['contentTypes']) ]; } $config = [ 'is_gallery' => false, 'content' => '', 'taxonomies' => [] ]; $type = get_queried_object(); if (is_post_type_archive() || is_singular()) { $content = is_singular() ? jvbNoBase($type->post_type) : jvbNoBase($type->name); $registrar = Registrar::getInstance($content)??false; if ($registrar) { $config = array_merge($config, $registrar->getConfig('feed')); } else { $config['content'] = $content; $config['icon'] = jvbDefaultIcon(); } if (is_singular()) { $config['source'] = $type->ID; } $config['taxonomies'] = $this->getTaxonomies([$content]); } elseif (is_tax()) { $content = jvbNoBase($type->taxonomy); $registrar = Registrar::getInstance($content)??false; if ($registrar) { $config['content'] = $registrar->registrar->for; $config['context'] = $content; $config['taxonomies'] = $this->getTaxonomies($registrar->registrar->for); if (!empty($registrar->getConfig('feed'))){ $config = array_merge($config, $registrar->getConfig('feed')); } } $config['source'] = $type->term_id; } if (!is_array($config['content'])) { $config['content'] = [$config['content']]; } return $config; } /** * Get taxonomies for given content types */ protected function getTaxonomies(array $content): array { $taxonomies = []; foreach ($content as $contentType) { $registrar = Registrar::getInstance($contentType); if (!$registrar) { continue; } $contentTaxonomies = $registrar->registrar->taxonomies; $contentTaxonomies = array_filter($contentTaxonomies, function($taxonomy) { return Registrar::getInstance($taxonomy)?->hasFeature('show_feed'); }); $taxonomies = array_merge($taxonomies, $contentTaxonomies); } return array_unique($taxonomies); } public function render(array $attributes, string $content, WP_Block $block) { $this->config = $this->buildParams($attributes); return $this->cache->remember( $this->cache->generateKey($this->config), function() { return $this->renderBlock(); } ); } protected function getContext():string|bool { return array_key_exists('context', $this->config)?$this->config['context']:false; } protected function getIDS():array|bool { return (array_key_exists('ids', $this->config) && !empty($this->config['ids'])) ? $this->config['ids'] : false; } protected function getClasses():array|bool { return array_key_exists('classes', $this->config) && !empty($this->config['classes']) ? $this->config['classes'] : false; } protected function getSource():string|bool { return array_key_exists('source', $this->config) ? $this->config['source'] : false; } protected function getIcon():string|bool { return array_key_exists('icon', $this->config) ? $this->config['icon'] : false; } protected function isGallery():bool { return (array_key_exists('is_gallery', $this->config) && $this->config['is_gallery']); } protected function getContent():array|bool { return (array_key_exists('content', $this->config) && !empty ($this->config['content'])) ? $this->config['content'] : false; } protected function renderBlock(): string { if (is_post_type_archive(BASE.'directory')) { return ''; } $ids = ($this->getIDS()) ? ' id="'.implode(' ',$this->getIDS()).'"' : ''; $classes = ($this->getClasses()) ? ' class="'.implode(' ',$this->getClasses()).'"' : ''; $source = ($this->getSource()) ? ' data-source="'.$this->getSource().'"' : ''; $context = ($this->getContext()) ? ' data-context="'.$this->getContext().'"' : ''; $icons = ($this->getIcon()) ? ' data-icon="'.$this->getIcon().'"' : ' data-icon="'.jvbLogoIcon().'"'; $gallery = $this->isGallery() ? ' data-gallery' : ''; $content = ($this->getContent()) ? ' data-content="'.implode(',',$this->getContent()).'"' : ''; ob_start(); ?> class="feed-block"> renderFilters(); $this->renderGrid(); $this->renderLoader(); $this->renderTemplates(); echo TaxonomySelector::outputSelectorModal(); ?> config)) { return; } $feedContent = $this->getFeedContent(); $hasMany = count($this->getContent()) > 1; ?>
SHOWING: getContent() as $i => $type) : $checked = $i === 0 ? ' checked' : ''; $label = $feedContent[$type]['plural'] ?? ucfirst($type); ?> >
    $label) { $active = $i === 0 ? ' class="active"' : ''; ?>
  • >
config['taxonomies'])) { ?>
FILTER BY: config['taxonomies'] as $tax) : $registrar = Registrar::getInstance($tax)??false; if (!$registrar) continue; $contentForTax = $registrar->registrar->for; $hidden = empty($contentForTax) ? ' hidden' : ''; $taxSelector = new TaxonomySelector( 'feed-'.$tax, $tax, [ 'icon' => $registrar->getIcon()??jvbLogoIcon(), 'update' => '.selected-items-section .selected-items', 'types' => $contentForTax, 'autocomplete' => false, 'hidden' => $hidden, 'output' => 'minimal' ] ); echo $taxSelector->render(); endforeach; ?>
'match'])) ?>
ORDER BY: getContent() as $content) { $registrar = Registrar::getInstance($content)??false; if ($registrar && !empty($registrar->config('feed')->getCustomOrder())) { $custom = array_merge_recursive($custom, $registrar->config('feed')->getCustomOrder()); } } foreach ($custom as $slug => $conf) { ?>
ORDER:
getContent()) - 1; for ($i = 1; $i <= 36; $i++) { $rand = rand(0, $total); $config = Registrar::getInstance($this->getContent()[$rand]); $icon = jvbIcon($config->getIcon??jvbLogoIcon()); ?>
config)) { jvbRenderGallery(); } } protected function renderTemplates(): void { if ($this->getContent()) { foreach ($this->getContent() as $content) { echo $this->getDefaultTemplate($content); } } echo ''; echo ''; echo ''; } protected function getFavouritesButton(string $content):string { $registrar = Registrar::getInstance($content); if (!$registrar || !Site::has('favourites') || !$registrar->hasFeature('favouritable')) { return ''; } return ''; } protected function getUpvotesButton(string $content):string { $registrar = Registrar::getInstance($content); if (!Site::has('karma') || !$registrar || !$registrar->hasFeature('karma')){ return ''; } return '
'; } protected function getDefaultTemplate(string $content): string { $config = Registrar::getInstance($content)->getConfig('feed'); $allFields = Registrar::getFieldsFor($content); $images = $config['images']??['post_thumbnail']; $fields = $config['fields']??['post_title','post_date','post_excerpt']; $fields = array_filter($fields, function($field) use($images) { return !in_array($field, $images); }); $fields = array_filter($allFields, function($field) use($fields) { return in_array($field, $fields); }, ARRAY_FILTER_USE_KEY); $template = '
'.$this->getFavouritesButton($content).$this->getUpvotesButton($content); //Add all defined images, but allow for filtering $imageTemplate = ''; foreach ($images as $image) { $imageTemplate .= ''; } $imageTemplate .= ''; $template .= '
'.apply_filters('jvbFeedImages', $imageTemplate, $content, $images).'
'; //Output default fields, but allow for filtering $template .= '
'.apply_filters('jvbFeedItemSummary', jvbIcon('dots-three'), $content).''; $fieldsTemplate = ''; foreach ($fields as $fieldName => $config) { $fieldsTemplate .= apply_filters('jvbFeedItemField', $this->defaultFieldTemplate($config['type'], $fieldName), $content, $fieldName, $config['type']); } $template .= '
'.apply_filters('jvbFeedItemFields', $fieldsTemplate, $content, $fields).'
'; $template .= '
'; return ''; } protected function defaultFieldTemplate(string $fieldType, string $fieldName):string { $data = ' data-field="'.$fieldName.'"'; switch ($fieldName) { case 'post_title': return ''; case 'post_date': case 'post_modified': return ''; } return match($fieldType) { 'upload' => '', 'taxonomy' => '
  • ', default => '

    ', }; } /** * Get feed content using Features instead of get_option * Returns array of slug => config for types that show in feed */ public function getFeedContent(): array { return JVB()->routes('feed')->getFeedTypesConfig(); } }