I have a problem on a website between Elementor Pro and ACF pro. It seems to be with the photo galleries, but I’m not sure. The error that appears is the following:
PHP: 2024-08-02 13:43:19 [error X 3][/var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor-pro/modules/dynamic-tags/acf/tags/acf-gallery.php::48] Uncaught TypeError: Cannot access offset of type string on string in /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor-pro/modules/dynamic-tags/acf/tags/acf-gallery.php:48
Stack trace:
#0 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/data-tag.php(44): ElementorPro\Modules\DynamicTags\ACF\Tags\ACF_Gallery->get_value()
#1 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/manager.php(216): Elementor\Core\DynamicTags\Data_Tag->get_content()
#2 [internal function]: Elementor\Core\DynamicTags\Manager->get_tag_data_content()
#3 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/manager.php(109): call_user_func_array()
#4 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/manager.php(70): Elementor\Core\DynamicTags\Manager->parse_tag_text()
#5 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/controls/base-data.php(91): Elementor\Core\DynamicTags\Manager->parse_tags_text()
#6 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/controls-stack.php(1329): Elementor\Base_Data_Control->parse_tags()
#7 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/controls-stack.php(1176): Elementor\Controls_Stack->parse_dynamic_settings()
#8 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/post.php(298): Elementor\Controls_Stack->get_parsed_dynamic_settings()
#9 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/dynamic-css.php(36): Elementor\Core\Files\CSS\Post->render_styles()
#10 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/dynamic-css.php(40): Elementor\Core\DynamicTags\Dynamic_CSS->render_styles()
#11 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/post.php(178): Elementor\Core\DynamicTags\Dynamic_CSS->render_styles()
#12 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/base.php(680): Elementor\Core\Files\CSS\Post->render_css()
#13 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/base.php(180): Elementor\Core\Files\CSS\Base->parse_content()
#14 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/base.php(131): Elementor\Core\Files\Base->update_file()
#15 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/base.php(227): Elementor\Core\Files\CSS\Base->update()
#16 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/post.php(201): Elementor\Core\Files\CSS\Base->enqueue()
#17 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/dynamic-tags/manager.php(488): Elementor\Core\Files\CSS\Post->enqueue()
#18 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp-hook.php(324): Elementor\Core\DynamicTags\Manager->after_enqueue_post_css()
#19 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#20 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/plugin.php(517): WP_Hook->do_action()
#21 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/base.php(274): do_action()
#22 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/files/css/post.php(201): Elementor\Core\Files\CSS\Base->enqueue()
#23 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/frontend.php(1134): Elementor\Core\Files\CSS\Post->enqueue()
#24 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/jet-tabs/includes/addons/jet-accordion-widget.php(1071): Elementor\Frontend->get_builder_content()
#25 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/controls-stack.php(2325): Elementor\Jet_Accordion_Widget->render()
#26 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/widget-base.php(635): Elementor\Controls_Stack->render_by_mode()
#27 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/widget-base.php(776): Elementor\Widget_Base->render_content()
#28 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(483): Elementor\Widget_Base->print_content()
#29 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(1422): Elementor\Element_Base->print_element()
#30 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(483): Elementor\Element_Base->print_content()
#31 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(1422): Elementor\Element_Base->print_element()
#32 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(483): Elementor\Element_Base->print_content()
#33 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(1422): Elementor\Element_Base->print_element()
#34 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/base/element-base.php(483): Elementor\Element_Base->print_content()
#35 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/base/document.php(1875): Elementor\Element_Base->print_element()
#36 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/base/document.php(1800): Elementor\Core\Base\Document->do_print_elements()
#37 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/core/base/document.php(1201): Elementor\Core\Base\Document->print_elements()
#38 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/frontend.php(1158): Elementor\Core\Base\Document->print_elements_with_wrapper()
#39 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-content/plugins/elementor/includes/frontend.php(1053): Elementor\Frontend->get_builder_content()
#40 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp-hook.php(324): Elementor\Frontend->apply_builder_in_content()
#41 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/plugin.php(205): WP_Hook->apply_filters()
#42 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php(1871): apply_filters()
#43 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/rest-api/endpoints/class-wp-rest-posts-controller.php(958): WP_REST_Posts_Controller->prepare_item_for_response()
#44 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/rest-api/class-wp-rest-server.php(1230): WP_REST_Posts_Controller->update_item()
#45 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/rest-api/class-wp-rest-server.php(1063): WP_REST_Server->respond_to_request()
#46 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/rest-api/class-wp-rest-server.php(439): WP_REST_Server->dispatch()
#47 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/rest-api.php(420): WP_REST_Server->serve_request()
#48 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp-hook.php(324): rest_api_loaded()
#49 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#50 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/plugin.php(565): WP_Hook->do_action()
#51 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp.php(418): do_action_ref_array()
#52 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/class-wp.php(813): WP->parse_request()
#53 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-includes/functions.php(1336): WP->main()
#54 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/wp-blog-header.php(16): wp()
#55 /var/www/vhosts/eltallerdeverdes.com/003.eltallerdeverdes.com/index.php(17): require(‘…’)
#56 {main}
I would love to hear some thoughts on this one.
I have multiple blocks on which I have a custom field for adding width classes to the block (I don’t like Gutenbergs approach, I need my own). The selected class is appended to the blocks other regular css classes on the object.
On my ACF blocks I use get_block_wrapper_attributes() to get the classes and then add them to a wrapper div. Apparently these classes is also added to the preview wrapping div in admin which means I get a double effect of my css rules.
It removes the attribute classes on the inner div whenever clicking on the block but it’s back again whenever I reload the page.
Anyone got a clue on why this happens and how I can solve it (my soultion mught be bad, I’m of course open for other totally different solutions)? This worked fine, as far as I know, before the summer (just got back to work and discovered this after updating WP 6.2.2 -> 6.3. and ACF 6.1.7 -> 6.2.0).
Preferably I would not want these classes on the preview wrapping div, however they should in that case not be removed on the inner div when clicking on the preview.
My block code:
<?php
$custom_wrapper_classes = 'my-block';
include_once (get_stylesheet_directory() . '/includes/blocks/block-functions.php');
if (function_exists('hest_get_wrapper_attr')) :
$wrapper_attributes = hest_get_wrapper_attr($block, $custom_wrapper_classes);
endif;
$posts = get_field('my_relationship_field');
if( $posts ): ?>
<div <?php echo wp_kses_data($wrapper_attributes); ?>>
<div class="my-grid">
<?php
global $post;
foreach( $posts as $post):
setup_postdata($post);?>
<!-- Code for outputting data -->
<?php
endforeach; ?>
</div><!-- .my-grid -->
</div><!-- .wrapper -->
<?php
wp_reset_postdata();
endif; ?>
hest_get_wrapper_attr() looks like this:
<?php
/*
* Converts Gutenberg saved data attributes (input field by IPM plugin) to
* a string to echo on the wrapping div
*/
function conv_data_attributes($data_attributes) {
$data_attr = '';
// Regular expression pattern to match the value inside the brackets
$pattern = '/\[(.*?)\]/';
// Perform the regular expression match
if (preg_match_all($pattern, $data_attributes, $matches)) {
// Extract the matched values
$values = $matches[1];
// Remove the commas from each extracted value
$data_attr = array_map(function ($value) {
return str_replace(',', '', $value);
}, $values);
// Convert the array into a space-separated string
$data_attr = implode(' ', $data_attr);
}
return $data_attr;
}
/*
* Converts Gutenberg saved gap value to CSS
*
*/
function conv_blockgap_value($gap) {
$pattern = "/var:([^|]+)\|([^|]+)\|([^|]+)/";
$result = preg_replace_callback($pattern, function ($matches) {
$lastValue = $matches[3];
$updatedLastValue = preg_replace("/(\d+)([a-zA-Z]?)/", "$1-$2", $lastValue);
return "var(--wp--{$matches[1]}--{$matches[2]}--{$updatedLastValue})";
}, $gap);
$gap = "gap: " . $result . ";";
return $gap;
}
/*
* Main function to prepare all wrapper classes, styles and attributes
*
*/
function hest_get_wrapper_attr($block, $custom_wrapper_classes) {
$wrapper_attributes = '';
$alignment_classes = '';
$style = '';
// Support custom anchor values.
$anchor = '';
if ( ! empty( $block['anchor'] ) ) {
$anchor = 'id="' . esc_attr( $block['anchor'] ) . '" ';
$wrapper_attributes .= $anchor;
}
// Create class attribute allowing for custom "className" and "align" values.
if ( ! empty( $block['align'] ) ) {
$alignment_classes .= ' align' . $block['align'];
}
if ($block['supports']['alignContent'] == 'matrix') {
// If matrix
// Replace spaces: center left becomes center-left
$alignment_classes .= ' has-custom-content-position is-position-' . str_replace(" ", "-", $block['alignContent']);
} else {
if ( ! empty( $block['alignContent'] ) ) {
// If not matrix, get the alignContent
// either top, center, or bottom
$alignment_classes .= ' is-vertically-aligned-' . $block['alignContent'];
}
}
// Block text alignment
if( !empty($block['alignText']) ) {
$alignment_classes .= ' has-text-align-' . $block['alignText'];
}
// Check if the block has fullHeight turned on
if( !empty($block['fullHeight']) ) {
$style .= 'min-height: 100vh;';
}
// Check if we got custom data attributes to add to our main div
$data_attr = $block['dataAttributes'] ?? null;
if ($data_attr && function_exists('conv_data_attributes') ) :
$data_attr = conv_data_attributes($data_attr);
endif;
// Add blockGap value to wrapper attributes
$gap = $block['style']['spacing']['blockGap'] ?? null;
if ($gap && function_exists('conv_blockgap_value') ) :
$gap = conv_blockgap_value($gap);
endif;
$style .= $gap;
$wrapper_attributes .= get_block_wrapper_attributes(
[
'class' => $custom_wrapper_classes . $alignment_classes,
'style' => $style,
]
);
$wrapper_attributes = $wrapper_attributes . ' ' . $data_attr;
return $wrapper_attributes;
}
Hi there,
I’m trying to build a more flexible template that allows the user to simply add content blocks that can be moved around using “Add Row” and then selecting from a dropdown of template blocks. I was using the advanced layout template as a guide and duplicated a number of content/template files. Exported the PHP and added to bottom of the function.php file, as well.
The problem is that when I try to use the new template, the “Add row” button doesn’t show up, so I can’t even tell if it’s partially working. I tried adding the new segments to the Advanced Layout Template but they don’t show up in the drop down either.
All of the new template files I’ve added were pulled from already existing template files, so I know they can work, but need something that’s not so rigid, as we currently can’t change anything or change the order without effecting every site on our website, and if we do add something, it simply doesn’t show up.
A number of the new field groups have custom names, not sure if that matters, tried just applying a new, different template to the page we want to change, but if I do that the page becomes blank on the front end, even though the back end shows content.
Here’s our template PHP page.
<?php
/**
* Template Name: Master Page Builder
*/
?>
<?php while (have_posts()) : the_post(); ?>
<?php //get_template_part('templates/page', 'header'); ?>
<?php get_template_part('templates/content', 'master-page-builder'); ?>
<?php endwhile; ?>
The content file associated with the template file is below.
<?php
// SETTINGS *** Lines 3-11, possibly unnecessary **
global $post;
$pid = $post->ID;
$pSlug = $post->slug;
$parentID = $post->post_parent;
// print $pid;
// print '<br>';
// print $parentID;
//$title = get_field('title');
$colour = get_field('theme_colour');
$hide_content = get_field('hide_content');
?>
<div class="trufflesTheme_<?php if ($colour) : print $colour; else : print 'indigo'; endif; ?> trufflesChildPage">
<?php
if ($hide_content) :
// Return Nothing
else : ?>
<section id="trufflesMainContent" class="sectionRow truffles_content">
<div class="inner">
<div class="margin">
<?php the_content(); ?>
</div>
</div>
</section>
<?php endif; ?>
<?php if (have_rows('master_content_type')) : ?>
<section id="truffles_contentWrapper" class="truffles_contentType truffles_content">
<?php while (have_rows('master_content_type')) : the_row();
// Available Variables under sub field 'select'
//full : Full Banner
//small : Smaller Banner
//imageanddesc : Image & Description
//altimageanddesc : Image & Description (Alternative)
//wysiwyg : Content Editor (WYSIWYG)
//accordions : Accordions
//logocloud : Logo Cloud
//photocolumns : Photo Columns
//topbanner : Header Banner
//introduction : Introduction & Booking
//cta : Call To Action
//testimonials: Testimonials
//testimonials: Video Banner
//linkblocks: Link Blocks
//homepageimgdesc: Image & Description Home Page Styling
//bannerheader: Text Header
$select = get_sub_field('select'); ?>
<section class="contentType_<?php print $select; ?> sectionRow">
<?php if ($select == 'full') : ?>
<?php get_template_part('templates/advanced', 'full'); ?>
<?php elseif ($select == 'small') : ?>
<?php get_template_part('templates/advanced', 'small'); ?>
<?php elseif ($select == 'imageanddesc') : ?>
<?php get_template_part('templates/advanced', 'imageanddesc'); ?>
<?php elseif ($select == 'altimageanddesc') : ?>
<?php get_template_part('templates/advanced', 'altimageanddesc'); ?>
<?php elseif ($select == 'wysiwyg') : ?>
<?php get_template_part('templates/advanced', 'wysiwyg'); ?>
<?php elseif ($select == 'accordions') : ?>
<?php get_template_part('templates/advanced', 'accordions'); ?>
<?php elseif ($select == 'logocloud') : ?>
<?php get_template_part('templates/advanced', 'logocloud'); ?>
<?php elseif ($select == 'photocolumns') : ?>
<?php get_template_part('templates/advanced', 'photocolumns'); ?>
<?php elseif ($select == 'three') : ?>
<?php get_template_part('templates/advanced', 'threecolumns'); ?>
<?php elseif ($select == 'embed') : ?>
<?php get_template_part('templates/advanced', 'embed'); ?>
<!-- New Content Fields -->
<?php elseif ($select == 'topbanner') : ?>
<?php get_template_part('templates/advanced', 'topbanner'); ?>
<?php elseif ($select == 'introduction') : ?>
<?php get_template_part('templates/advanced', 'introduction'); ?>
<?php elseif ($select == 'cta') : ?>
<?php get_template_part('templates/advanced', 'cta'); ?>
<?php elseif ($select == 'testimonials') : ?>
<?php get_template_part('templates/advanced', 'testimonials'); ?>
<?php elseif ($select == 'videobanner') : ?>
<?php get_template_part('templates/advanced', 'videobanner'); ?>
<?php elseif ($select == 'linkblocks') : ?>
<?php get_template_part('templates/advanced', 'linkblocks'); ?>
<?php elseif ($select == 'homepageimgdesc') : ?>
<?php get_template_part('templates/advanced', 'homepageimgdesc'); ?>
<?php elseif ($select == 'bannerheader') : ?>
<?php get_template_part('templates/advanced', 'bannerheader'); ?>
<!-- END New Content Fields -->
<?php endif; ?>
</section>
<?php endwhile; ?>
</section> <!-- END #truffles_contentWrapper -->
<?php endif; ?>
<?php get_template_part('templates/footer-landing'); ?>
</div><!-- end .trufflesTheme -->
And this is referencing a number of built out fields built in php, modelled after the structure of the advanced layout template.
Example below:
<?php
// TESTIMONIALS
$testimonials_section = get_sub_field('testimonials_section');
?>
<div class="innerTable">
<?php if($testimonials_section['section_content'] || $testimonials_section['testimonials_slider']):?>
<div class="testimonials-section">
<div class="container-wrap">
<?php if($testimonials_section['section_content']):?>
<div class="section-content">
<?php echo $testimonials_section['section_content'];?>
</div>
<?php endif;?>
<?php if($testimonials_section['testimonials_slider']):
echo testimonial_slider($testimonials_section['testimonials_slider']);
endif;?>
</div>
</div>
<?php endif;?>
</div>
Which is very similar to the advanced layout template fields, like this one below.
<?php
// VARIABLES
$image = get_sub_field(‘image’);
$desc = get_sub_field(‘description’);
?>
<div class=”innerTable”>
<?php if ($image) : ?>
<div class=”tableLeft”>
<div class=”imageBlock”>
<div class=”image”>
” alt=”Truffles Catering – <?php $image[‘alt’]; ?>” />
</div>
</div>
</div>
<?php endif; ?>
<?php if ($desc) : ?>
<div class=”tableRight”>
<div class=”descBlock”>
<div class=”desc”>
<?php print $desc; ?>
</div>
</div>
</div>
<?php endif; ?>
</div>
And lastly, here’s the PHP that I exported and added to the functions.php file.
/**
*
* Adding New Template and Registering it
*
* */
add_action( 'acf/include_fields', function() {
if ( ! function_exists( 'acf_add_local_field_group' ) ) {
return;
}
acf_add_local_field_group( array(
'key' => 'group_649377b3715ff',
'title' => 'Master Page Builder',
'fields' => array(
array(
'key' => 'field_649377b3bddda',
'label' => 'Master Content Type',
'name' => 'master_content_type',
'aria-label' => '',
'type' => 'repeater',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'collapsed' => '',
'min' => 0,
'max' => 0,
'layout' => 'block',
'button_label' => 'Add Content Row',
'sub_fields' => array(
),
),
array(
'key' => 'field_6493785744c19',
'label' => 'Navigation Menu',
'name' => 'navigation_menu',
'aria-label' => '',
'type' => 'select',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'choices' => array(
'main-navigation' => 'Main Navigation',
'secondary-menu' => 'Secondary Menu',
'footer-menu' => 'Footer Menu',
'weddings-menu' => 'Weddings Menu',
'corporate-functions-menu' => 'Corporate Functions Menu',
'social-events-menu' => 'Social Events Menu',
'truffles-express-menu' => 'Truffles Express Menu',
),
'default_value' => false,
'return_format' => 'value',
'multiple' => 0,
'allow_null' => 0,
'ui' => 0,
'ajax' => 0,
'placeholder' => '',
),
),
'location' => array(
array(
array(
'param' => 'page_template',
'operator' => '==',
'value' => 'template-master-page-builder.php',
),
),
),
'menu_order' => 0,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => true,
'description' => '',
'show_in_rest' => 0,
) );
} );
Surely, it can’t be this difficult to use ACF? Can anyone help me get this to be visible so I can add content blocks on our back-end that anyone can add, move, and (most importantly) be seen on the front-end.
Thank you
Certain keywords in the search seem to break the search results page!
https://support.advancedcustomfields.com/forums/search?bbp_search=wrap+main+content
Hi,
I would like to know how could i use ACF to create reusable component fields that can be managed from one place, let’s say inside the options page.
I’ve tried using clone fields for that but the values don’t get synced between the main and the clones. No matter if the slug has a prefix or not.
Right now i’ve created a way in which i use ACF prepare_field filter. This works for simple fields but i’m not sure how could i use the same logic on for example repeater fields.
Here’s the code i’m running right now
add_filter('acf/prepare_field', function($field){
$current_screen = get_current_screen();
if($current_screen && $current_screen->id == 'toplevel_page_theme-settings') return $field;
$components = get_field('components', 'option');
foreach($components as $component){
if(array_key_exists($field['_name'], $component)){
if(isset($field['sub_fields'])){
foreach($field['sub_fields'] as $field_key => $sub_field){
foreach($component[$field['_name']] as $sub_component){
if(array_key_exists($sub_field['_name'], $sub_component)){
//$field['sub_fields'][$field_key]['value'] = $sub_component[$sub_field['_name']];
//consoleLog([$field, $sub_field, $sub_component[$sub_field['_name']]]);
}
}
}
}else{
$field['value'] = $component[$field['_name']];
}
}
}
return $field;
},10,3)
And here’s the ACF output for components field group
{
"key": "field_638edca18a922",
"label": "Components",
"name": "",
"aria-label": "",
"type": "tab",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"placement": "left",
"endpoint": 0
},
{
"key": "field_638edcad8a923",
"label": "Components",
"name": "components",
"aria-label": "",
"type": "flexible_content",
"instructions": "Reusable components that can be managed from one place",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"layouts": {
"layout_638edcb3c4b41": {
"key": "layout_638edcb3c4b41",
"name": "get_in_touch",
"label": "Get In Touch",
"display": "block",
"sub_fields": [
{
"key": "field_638edcc28a924",
"label": "Heading",
"name": "get_in_touch_heading",
"aria-label": "",
"type": "textarea",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"maxlength": "",
"rows": 3,
"placeholder": "",
"new_lines": ""
},
{
"key": "field_638edcd28a925",
"label": "Button",
"name": "get_in_touch_button",
"aria-label": "",
"type": "link",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "array"
}
],
"min": "",
"max": ""
},
"layout_638f209874700": {
"key": "layout_638f209874700",
"name": "icon_group",
"label": "Icon group",
"display": "block",
"sub_fields": [
{
"key": "field_638f20b774701",
"label": "Icon group",
"name": "icon_group",
"aria-label": "",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"layout": "table",
"min": 0,
"max": 0,
"collapsed": "",
"button_label": "Add Row",
"rows_per_page": 20,
"sub_fields": [
{
"key": "field_638f20ca74702",
"label": "Icon",
"name": "icon",
"aria-label": "",
"type": "image",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "array",
"library": "all",
"min_width": "",
"min_height": "",
"min_size": "",
"max_width": "",
"max_height": "",
"max_size": "",
"mime_types": "",
"preview_size": "thumbnail",
"parent_repeater": "field_638f20b774701"
},
{
"key": "field_638f20da74703",
"label": "Background",
"name": "background",
"aria-label": "",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"enable_opacity": 0,
"return_format": "string",
"parent_repeater": "field_638f20b774701"
}
]
}
],
"min": "",
"max": ""
}
},
"min": "",
"max": "",
"button_label": "Add component"
}
For “Get In Touch” gield group it works but for “Icon Group” i’m not sure how to exactly achieve that.
I’m trying to add a text acf to a custom page template with a custom posts loop.
There are other ACFs on the page however my ACF does not show on the front end unless I place it outside the loop. Below is my code. My call to the ACF in question is <?php the_field(‘post_archive_subheading’); ?> and it won’t work inside the loop.
<?php
/* Template Name: Archive Page Custom */
?>
<?php
/**
* Post archive template.
*
* @link https://codex.wordpress.org/Template_Hierarchy
*
* @package XXXXXXX
*/
$featured_posts = get_field( 'featured_posts', get_option( 'page_for_posts' ) );
$not_in = array();
if ( $featured_posts && '' !== $featured_posts && 3 === count( $featured_posts ) ) :
foreach ( $featured_posts as $featured_post ) :
$not_in[] = $featured_post->ID;
endforeach;
endif;
$posts_args = array(
'posts_per_page' => '12',
'post__not_in' => $not_in,
'paged' => get_query_var( 'paged' ) ?: 1,
);
$posts_archive = new WP_Query( $posts_args );
get_header(); ?>
<main id="main" class="site-main custom-page-content">
<?php get_template_part( 'template-parts/content', 'page-single-hero' ); ?>
<div class="entry-content page-content blog">
<?php the_content(); ?>
</div><!-- .entry-content -->
<?php if ( has_nav_menu( 'post-categories' ) ) : ?>
<nav class="post-categories-navigation" aria-label="<?php esc_attr_e( 'Post Categories Navigation', 'ventura-county-coast' ); ?>">
<button
id="toggle-categories"
class="toggle-categories-button hidden"
aria-pressed="false"
type="button"
>
<?php
esc_html_e( 'Categories', 'ventura-county-coast' );
vcc_display_svg(
array(
'icon' => 'close',
'width' => '16px',
'height' => '16px',
'fill' => '#5b5f60',
)
);
?>
</button>
<?php
wp_nav_menu(
array(
'fallback_cb' => false,
'theme_location' => 'post-categories',
'menu_class' => 'menu post-categories',
'container' => false,
)
);
?>
</nav><!-- .post-categories-navigation -->
<?php endif; ?>
<?php if ( $featured_posts && 3 === count( $featured_posts ) && ! is_paged() ) : ?>
<div class="featured-posts">
<?php
foreach ( $featured_posts as $key => $featured_post ) :
if ( 1 === $key ) :
?>
<div class="featured-end-wrap">
<?php
endif;
?>
<div class="featured featured-<?php echo esc_attr( $key + 1 ); ?>">
<?php
vcc_display_card(
array(
'image' => get_the_post_thumbnail_url( $featured_post->ID, 'full-width' ),
'title' => $featured_post->post_title,
'text' => vcc_get_the_excerpt(
array(
'post' => $featured_post->ID,
)
),
'class' => '',
'url' => get_permalink( $featured_post->ID ),
)
);
?>
</div><!-- .featured-# -->
<?php
if ( 2 === $key ) :
?>
</div><!-- .featured-end-wrap -->
<?php
endif;
endforeach;
?>
</div><!-- .featured-posts -->
<?php endif; // $featured_posts ?>
<?php
/* Start the Custom Loop */
$counter = 0;
if ( $posts_archive->have_posts() ) :
?>
<div class="grid posts-grid">
<?php
while ( $posts_archive->have_posts() ) :
$posts_archive->the_post();
?>
<div class="col col-4 col-md-6 col-sm">
<?php the_field('post_archive_subheading'); ?>
<?php
vcc_display_card(
array(
'image' => get_the_post_thumbnail_url( get_the_ID(), 'full-width' ),
'title' => get_the_title(),
'text' => vcc_get_the_excerpt(),
'class' => '',
'url' => get_the_permalink(),
)
);
?>
<?php if ( 2 === $counter ) : ?>
</div><!-- .col.col-4 -->
</div><!-- .grid -->
<?php get_template_part( 'template-parts/mailchimp-newsletter' ); ?>
<div class="grid posts-grid"><!-- Open a new .grid -->
<?php else : ?>
</div><!-- .col.col-4 -->
<?php endif; ?>
<?php
$counter++;
endwhile;
wp_reset_postdata();
vcc_display_numeric_pagination( $posts_args, $posts_archive );
?>
</div><!-- .grid -->
<?php
else :
get_template_part( 'template-parts/content', 'none' );
endif;
?>
</main><!-- #main -->
<?php get_footer(); ?>
For some reason, my acf field won’t save when we are not logged in. Here is an example on my code:
<?php
acf_form_head();
get_header();
acf_enqueue_uploader();
?>
<style>
section.fusion-tb-header {
display: none;
}
.avada-page-titlebar-wrapper {
display: none;
}
section.fusion-tb-footer.fusion-footer {
display: none;
}
div#wpadminbar{
display: none!important;
}
a#toTop {
display: none;
}
a.acf-button.button {
display: block;
border: solid 1px #c6d6e3;
text-align: center;
background: #c6d6e3;
color: #fff;
}
input.acf-button.button.button-primary.button-large {
background-color: #4a5f77;
border: 0px;
color: #fff;
width: 96%;
font-size: 20px;
font-weight: 600;
text-align: center;
margin: 0 auto;
display: block;
}
</style>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<?php while ( have_posts() ) : the_post(); ?>
<?php acf_form(array(
'post_id' => 123,
'field_groups' => array('group_62e4b1a600eab'),
'post_author' => 6,
'kses' => false,
'form_attributes' => array(
'enctype' => 'multipart/form-data',
)
)); ?>
<?php endwhile; ?>
<div class="buffer" style="display: block; height: 600px; width: 100%;"></div>
</main><!-- .site-main -->
</div>
<script src="https://asapwellmind.wpengine.com/wp-content/plugins/advanced-custom-fields-pro/assets/build/js/acf.min.js?ver=5.11" id="acf-js"></script>
<script src="https://asapwellmind.wpengine.com/wp-content/plugins/advanced-custom-fields-pro/assets/build/js/acf-input.min.js?ver=5.11" id="acf-input-js"></script>
<script src="https://asapwellmind.wpengine.com/wp-content/plugins/advanced-custom-fields-pro/assets/build/js/pro/acf-pro-input.min.js?ver=5.11" id="acf-pro-input-js"></script>
<script src="https://asapwellmind.wpengine.com/wp-content/plugins/advanced-custom-fields-pro/assets/inc/select2/4/select2.full.min.js?ver=4.0" id="select2-js"></script>
<?php get_footer(); ?>
Hello,
I am using ACF PRO and I have created a few fields for a home page slider and I am trying to set an expiration date for each slide (each row of ACF) for more than a week already. I have tried to follow a few posts on the internet but nothing actually worked.
I have created a field expiry_date at Custom Fields in the Back end using date time picker but I have no clue and succes on the codding to check if the date has passed = remove the row.
Here is my current code on my home page:
<?php if( have_rows('slider1')): ?>
<div class="main-slider" id="main-slider">
<div class="slider big-slider slider-wrap">
<?php while ( have_rows('slider1') ): the_row();
$highlight2 = get_sub_field('highlight1');
$heading2 = get_sub_field('heading1');
$date2 = get_sub_field('dateandtime1');
$live2 = get_sub_field('live1');
$description2 = get_sub_field('description1');
$linktext2 = get_sub_field('linktext1');
$button2 = get_sub_field('button1');
$image2 = get_sub_field('sliderimage1');
?>
<div class="slide slick-bg" style="background-image:url(<?php echo $image2['url'];?>">
<div class="container-fluid position-relative h-100">
<div class="slider-content h-100">
<div class="row align-items-center h-100">
<div class="col-xl-6 col-lg-12 col-md-12">
<h3 data-animation-in="fadeInUp" data-delay-in="1"><span class="badge bg-warning text-dark"><?php echo $highlight2;?></span></h3>
<h1 data-animation-in="fadeInUp" data-delay-in="1"><?php echo $heading2;?></h1>
<div class="slide-info" data-animation-in="fadeInUp" data-delay-in="1">
<span><?php echo $date2;?></span> <span class="radius"><?php echo $live2;?></span>
</div>
<p data-animation-in="fadeInUp" data-delay-in="1"><?php echo $description2;?>
<div class="slider-buttons d-flex align-items-center" data-animation-in="fadeInUp" data-delay-in="1">
<?php if($button2):?>
<a class="btn hvr-sweep-to-right" href="<?php echo $button2;?>" tabindex="0"><i aria-hidden="true" class="fas fa-plus mr-2"></i><?php echo $linktext2;?></a>
<?php endif;?>
</div>
</div>
</div>
</div>
</div>
</div>
<?php endwhile; ?>
</div>
</div>
<?php endif; ?>
Hello,
I try to display two loops from a custom post type in a template single page.
The first one is diplayed but not the second.
Thank for your help.
Here my code :
<?php
/*
Template Name: Comptes rendus
*/
get_header();
$show_default_title = get_post_meta( get_the_ID(), '_et_pb_show_title', true );
$is_page_builder_used = et_pb_is_pagebuilder_used( get_the_ID() );
?>
<div id="main-content">
<?php
if ( et_builder_is_product_tour_enabled() ):
// load fullwidth page in Product Tour mode
while ( have_posts() ): the_post(); ?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'et_pb_post' ); ?>>
<div class="entry-content">
<?php
the_content();
?>
</div> <!-- .entry-content -->
</article> <!-- .et_pb_post -->
<?php endwhile;
else:
?>
<div class="container">
<div id="content-area" class="clearfix">
<div id="left-area">
<?php while ( have_posts() ) : the_post(); ?>
<?php
/**
* Fires before the title and post meta on single posts.
*
* @since 3.18.8
*/
do_action( 'et_before_post' );
?>
<article id="post-<?php the_ID(); ?>" <?php post_class( 'et_pb_post' ); ?>>
<?php if ( ( 'off' !== $show_default_title && $is_page_builder_used ) || ! $is_page_builder_used ) { ?>
<div class="et_post_meta_wrapper">
<h1 class="entry-title"><?php the_title(); ?></h1>
<?php
$query2021 = new WP_Query( array(
'post_type' => 'comptes-rendus',
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'annee', // name of custom field
'value' => '2021', // matches exaclty "123", not just 123. This prevents a match for "1234"
'compare' => 'LIKE'
)
)
)
);
// The Query
if ( $query2021->have_posts() ) : ?>
<div class="entry-content" itemprop="text">
<table class="table-cr">
<thead>
<tr>
<th scope="col">Intitulé</th>
<th scope="col">Date</th>
<th scope="col">Fichier</th>
<th scope="col">Poids</th>
</tr>
</thead>
<?php // The Loop
$file = get_field('fichier');
while ( $query2021->have_posts() ) : $query2021->the_post(); ?>
<tbody>
<tr>
<td data-label="Intitulé"><?php the_field('intitule'); ?></td>
<td data-label="Date"><?php the_time( 'j.m.Y' ); ?></td>
<td data-label="Fichier"><a href="<?php the_field('fichier'); ?>" target="_blank" ><button>Télécharger</button></a></td>
<td data-label="Poids"><?php the_field('poids'); ?></td>
</tr>
<?php endwhile; wp_reset_query(); ?>
</tbody>
</table>
</div>
<?php
$query2020 = new WP_Query( array(
'post_type' => 'comptes-rendus',
'orderby' => 'date',
'order' => 'DESC',
'meta_query' => array(
array(
'key' => 'annee', // name of custom field
'value' => '2020', // matches exaclty "123", not just 123. This prevents a match for "1234"
'compare' => 'LIKE'
)
)
)
);
// The Query
elseif ( $query2020->have_posts() ) : ?>
<div class="entry-content" itemprop="text">
<table class="table-cr">
<thead>
<tr>
<th scope="col">Intitulé</th>
<th scope="col">Date</th>
<th scope="col">Fichier</th>
<th scope="col">Poids</th>
</tr>
</thead>
<?php // The Loop
$file = get_field('fichier');
while ( $query2020->have_posts() ) : $query2020->the_post(); ?>
<tbody>
<tr>
<td data-label="Intitulé"><?php the_field('intitule'); ?></td>
<td data-label="Date"><?php the_time( 'j.m.Y' ); ?></td>
<td data-label="Fichier"><a href="<?php the_field('fichier'); ?>" target="_blank" ><button>Télécharger</button></a></td>
<td data-label="Poids"><?php the_field('poids'); ?></td>
</tr>
<?php endwhile; wp_reset_query(); ?>
</tbody>
</table>
</div>
<?php endif;
?>
</div> <!-- .et_post_meta_wrapper -->
<?php } ?>
<div class="entry-content">
<?php
do_action( 'et_before_content' );
the_content();
wp_link_pages( array( 'before' => '<div class="page-links">' . esc_html__( 'Pages:', 'Divi' ), 'after' => '</div>' ) );
?>
</div> <!-- .entry-content -->
<div class="et_post_meta_wrapper">
<?php
if ( et_get_option('divi_468_enable') === 'on' ){
echo '<div class="et-single-post-ad">';
if ( et_get_option('divi_468_adsense') !== '' ) echo et_core_intentionally_unescaped( et_core_fix_unclosed_html_tags( et_get_option('divi_468_adsense') ), 'html' );
else { ?>
<a href="<?php echo esc_url(et_get_option('divi_468_url')); ?>"><img src="<?php echo esc_attr(et_get_option('divi_468_image')); ?>" alt="468" class="foursixeight" /></a>
<?php }
echo '</div> <!-- .et-single-post-ad -->';
}
/**
* Fires after the post content on single posts.
*
* @since 3.18.8
*/
do_action( 'et_after_post' );
if ( ( comments_open() || get_comments_number() ) && 'on' === et_get_option( 'divi_show_postcomments', 'on' ) ) {
comments_template( '', true );
}
?>
</div> <!-- .et_post_meta_wrapper -->
</article> <!-- .et_pb_post -->
<?php endwhile; ?>
</div> <!-- #left-area -->
<?php get_sidebar(); ?>
</div> <!-- #content-area -->
</div> <!-- .container -->
<?php endif; ?>
</div> <!-- #main-content -->
<?php
get_footer();
I maintain a wordpress plugin in which we use ACF to add optional fields to the edit page for every post. In production (wordpress 5.4.2), this is working as expected.
When testing this in a new local wordpress instance (5.7.2, with the Classic Editor plugin to bypass Gutenburg), the entire “acf-input” section is missing including the add button for each field.
This is the hook being called to load the fields:
acf_add_local_field_group(
array(
'key' => 'group_d5a22594839cd',
'title' => 'Field group title here',
'fields' => array(
array(
'key' => 'field_496edd4619978',
'label' => 'Article',
'name' => 'plugin_prefix_article',
'type' => 'flexible_content',
'instructions' => 'Field instructions here',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'layouts' => array(/* removed layouts for verbosity sake */),
'button_label' => 'Add Article',
'min' => '',
'max' => '',
),
array(
'key' => 'field_55f0cfc948b46',
'label' => 'Product',
'name' => 'plugin_prefix_product',
'type' => 'flexible_content',
'instructions' => 'Field instructions here',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'layouts' => array(/* removed layouts for verbosity sake */),
'button_label' => 'Add Product',
'min' => '',
'max' => '',
),
),
'location' => array(
array(
array(
'param' => 'post_type',
'operator' => '==',
'value' => 'post',
),
),
),
'menu_order' => 10,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => '',
'active' => true,
'description' => 'Field group description here',
)
);
This feels like I’m missing something very basic, but I genuinely don’t know what it is.
Hello!
I am trying to create an FAQ repeater to my archive-product.php (category pages) in WooCommerce + Storefront but unfortunately, it’s not working. It skips right over the “if” statement and just says “Come back later”. Am I missing something here since I’ve never come across an issue like this and didn’t find a solution for this from anywhere else?
Full code of the template:
<?php
/**
* The Template for displaying product archives, including the main shop page which is a post type archive
*
* This template can be overridden by copying it to yourtheme/woocommerce/archive-product.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @package WooCommerce\Templates
* @version 3.4.0
*/
defined( 'ABSPATH' ) || exit;
get_header( 'shop' );
/**
* Hook: woocommerce_before_main_content.
*
* @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content)
* @hooked woocommerce_breadcrumb - 20
* @hooked WC_Structured_Data::generate_website_data() - 30
*/
do_action( 'woocommerce_before_main_content' );
?>
<header class="woocommerce-products-header">
<?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?>
<h1 class="woocommerce-products-header__title page-title"><?php woocommerce_page_title(); ?></h1>
<?php endif; ?>
<?php
/**
* Hook: woocommerce_archive_description.
*
* @hooked woocommerce_taxonomy_archive_description - 10
* @hooked woocommerce_product_archive_description - 10
*/
do_action( 'woocommerce_archive_description' );
?>
</header>
<?php
if ( woocommerce_product_loop() ) {
/**
* Hook: woocommerce_before_shop_loop.
*
* @hooked woocommerce_output_all_notices - 10
* @hooked woocommerce_result_count - 20
* @hooked woocommerce_catalog_ordering - 30
*/
do_action( 'woocommerce_before_shop_loop' );
woocommerce_product_loop_start();
if ( wc_get_loop_prop( 'total' ) ) {
while ( have_posts() ) {
the_post();
/**
* Hook: woocommerce_shop_loop.
*/
do_action( 'woocommerce_shop_loop' );
wc_get_template_part( 'content', 'product' );
}
}
woocommerce_product_loop_end();
/**
* Hook: woocommerce_after_shop_loop.
*
* @hooked woocommerce_pagination - 10
*/
do_action( 'woocommerce_after_shop_loop' );
} else {
/**
* Hook: woocommerce_no_products_found.
*
* @hooked wc_no_products_found - 10
*/
do_action( 'woocommerce_no_products_found' );
}
?>
<div class="container FAQ">
<div class="row">
<div class="col-md-12">
<?php if( have_rows('faq') ):
$i = 1; // Set the increment variable
?>
<div id="accordion">
<?
// loop through the rows of data for the tab header
while ( have_rows('faq') ) : the_row();
?>
<div class="card" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">
<div class="card-header" id="heading-<?php echo $i;?>">
<button class="btn btn-link collapsed" data-toggle="collapse" data-target="#collapse-<?php echo $i;?>" aria-expanded="true" aria-controls="collapse-<?php echo $i;?>">
<span class="accordion-title" itemprop="name"><?php the_sub_field('question'); ?></span>
</button>
</div>
<div id="collapse-<?php echo $i;?>" class="collapse" aria-labelledby="heading-<?php echo $i;?>" data-parent="#accordion">
<div class="card-body" itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
<span itemprop="text"><?php the_sub_field('answer'); ?></span>
</div>
</div>
</div>
<?php $i++; // Increment the increment variable
endwhile; //End the loop
?>
</div>
<?php
else :
// no rows found
echo 'Come back later';
endif;?>
</div>
</div>
</div>
<?php
/**
* Hook: woocommerce_after_main_content.
*
* @hooked woocommerce_output_content_wrapper_end - 10 (outputs closing divs for the content)
*/
do_action( 'woocommerce_after_main_content' );
/**
* Hook: woocommerce_sidebar.
*
* @hooked woocommerce_get_sidebar - 10
*/
do_action( 'woocommerce_sidebar' );
get_footer( 'shop' );
Hey guys
We use ACF Pro for our company website. I have a repeater field set up which only displays images. When using an empty template file, only inserting the repeater code to collect one image everything is working fine and the image is showing up as expected.
Above mentioned code looks like this:
<?php
if( have_posts() ) : while( have_posts() ) : the_post( );
the_content(); ?>
<!-- Simple text field -->
<h2 style="margin: 10rem 0"><?php the_field('test-titel'); ?></h2>
<!-- Repeater field -->
<?php if( have_rows( 'post_image' ) ) :
while( have_rows( 'post_image' ) ) : the_row();
$image = get_sub_field( 'the_image' );
echo '<pre>'
print_r( $image )
echo '</pre>'
?>
<img style="max-width: 100%" src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>">
<?php endwhile; endif; ?>
<?php endwhile; endif; ?>
However when inserting the same code in the actual template file together with everything else (like get_header(), html and so on…) the image doesn’t appear anymore.
Also I’m not a fan of squeezing in lots of php code inside the existing html so I’d prefer to put it all above. However I’m not sure if this is possible – if this is what makes it break.
Because when inserting it at the top of the php file (before the html starts in order to make less of a mess) all content disappears and only header and footer is displayed. See excerpt below of my inserted code.
<?php get_header(); ?>
<?php
// The loop
if( have_posts() ) : while( have_posts() ) : the_post();
// Custom image field
if( have_rows( 'post_image' ) ) :
while( have_rows( 'post_image' ) ) : the_row();
$image = get_sub_field( 'the_image' ); ?>
<!-- CATEGORY LAYOUT -->
<div id="kits-main">
<div class="header-group">
<p class="header-group__header text-center">tjänster
<img src="<?php echo get_theme_file_uri( '/images/brand-separator-sm.svg' ); ?>" alt="" class="brand-separator" role="presentation">
<div class="kits-brand">
<div class="kits-brand__wrapper">
<p class="kits-brand__name"><?php the_title(); ?>
<p class="kits-brand__meaning">something something
</div>
</div>
</div>
<div class="container-lg">
<!-- BREADCRUMBS AND STUFF STILL NOT IMPLEMENTED -->
<!-- First pair of boxes -->
<div class="row">
<div class="col-lg-6 p-0">
<div class="column--1">
<div class="content-wrapper constrained">
<?php if( !empty( $image ) ): ?>
<img class="box-img box-img-1"
src="<?php echo esc_url($image['url']); ?>" alt="<?php echo esc_attr($image['alt']); ?>">
<?php endif; ?>
</div> <!-- End .content-wrapper -->
</div> <!-- End .box-column--1 -->
</div> <!-- End .col-6 p-0 -->
Last in the php document I close the ifs and whiles.
<?php endwhile; endif;?>
<?php endwhile; endif; ?>
<?php get_footer(); ?>
The result is that nothing is returned, at all. ALL the html is stripped out.
Earlier I put everything inside the div with class .content-wrapper .constrained and while it still didn’t produce any result, at least the other content still showed up as usual. I don’t like this approach though since it’s terribly messy.
Details:
Wp theme used: UnderStrap (latest)
ACF Pro version: 5.9.5
ACF Plugins installed: None
Any help is highly appreciated!
Hello ACF friends,
I am trying to register a field group via PHP and creating the layouts from other field groups, my procedure is as follows:
add_action('acf/init', function() {
$elements = [
'image_text'
];
$layouts = [];
foreach ($elements as $element) {
$acf_json_data = locate_template("inc/acf/exports/group_" . $element . ".json");
$data = $acf_json_data ? json_decode(file_get_contents($acf_json_data), true) : [];
if( !empty($data) ) {
$key = 'layout_' . $element;
$layout = [
'key' => $key,
'name' => $element,
'label' => $data[0]['title'],
'display' => 'block',
'sub_fields' => $data[0]['fields'],
'min' => '',
'max' => ''
];
$layouts[$key] = $layout;
}
}
acf_add_local_field_group(array(
'key' => 'group_main_content',
'title' => 'Content',
'fields' => array(
array(
'key' => 'field_main_content_flex_content',
'label' => 'Content',
'name' => 'flex_content',
'type' => 'flexible_content',
'instructions' => '',
'required' => 0,
'conditional_logic' => 0,
'wrapper' => array(
'width' => '',
'class' => '',
'id' => '',
),
'layouts' => $layouts,
'button_label' => 'Element hinzufügen',
'min' => '',
'max' => '',
),
),
'location' => array(
array(
array(
'param' => 'post_type',
'operator' => '==',
'value' => 'page',
),
),
),
'menu_order' => 1,
'position' => 'acf_after_title',
'style' => 'default',
'label_placement' => 'left',
'instruction_placement' => 'label',
'hide_on_screen' => array(
0 => 'the_content',
1 => 'excerpt',
2 => 'discussion',
3 => 'comments',
4 => 'revisions',
5 => 'slug',
6 => 'author',
7 => 'format',
8 => 'page_attributes',
9 => 'featured_image',
10 => 'categories',
11 => 'tags',
12 => 'send-trackbacks',
),
'active' => true,
'description' => 'beschreibung',
));
});
The field group I load as layout looks like this:
[
{
"key": "group_image_text",
"title": "Bild und Text",
"fields": [
{
"key": "field_image_text_image",
"label": "Bild",
"name": "image",
"type": "image",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "array",
"preview_size": "medium",
"library": "all",
"min_width": "",
"min_height": "",
"min_size": "",
"max_width": "",
"max_height": "",
"max_size": "",
"mime_types": ""
},
{
"key": "field_image_text_text",
"label": "Text",
"name": "text",
"type": "text",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": ""
}
],
"location": [
[
{
"param": "post_type",
"operator": "==",
"value": "post"
}
]
],
"menu_order": 2,
"position": "normal",
"style": "default",
"label_placement": "top",
"instruction_placement": "label",
"hide_on_screen": "",
"active": false,
"description": ""
}
]
This works quite well so far, and I have 3 questions about it.
1. does adding layouts make sense like this? Should I do it in a different way, or should I leave it better?
2. instead of creating the layouts myself, should I rather use the respective field group as a clone field in the layout?
3. i discovered the following little thing. Through an error I became aware of the validation.php. There I had the problem that in line 403 the filter threw an error, because the key $field[‘_name’] was missing.
At this point I’ve done a debug output of $field before this line. Than i found the following:
If the field group is registered using the backend, I have once in the field an ID (51) and a parent (50) and with each Sub Field likewise an ID () and a parent.
See here:
Array
(
[ID] => 51
[key] => field_flex_content
[label] => Content
[name] => flex_content
[prefix] => acf
[type] => flexible_content
[value] =>
[menu_order] => 0
[instructions] =>
[required] => 0
[id] =>
[class] =>
[conditional_logic] => 0
[parent] => 50
[wrapper] => Array
(
[width] =>
[class] =>
[id] =>
)
[layouts] => Array
(
[layout_image_text] => Array
(
[key] => layout_image_text
[name] => imageText
[label] => Bild & Text
[display] => block
[sub_fields] => Array
(
[0] => Array
(
[ID] => 48
[key] => field_image_text_image
[label] => Bild
[name] => imageTextImage
[prefix] => acf
[type] => image
[value] =>
[menu_order] => 0
[instructions] =>
[required] => 0
[id] =>
[class] =>
[conditional_logic] => 0
[parent] => 51
[wrapper] => Array
(
[width] =>
[class] =>
[id] =>
)
[parent_layout] => layout_image_text
[return_format] => array
[preview_size] => medium
[library] => all
[min_width] =>
[min_height] =>
[min_size] =>
[max_width] =>
[max_height] =>
[max_size] =>
[mime_types] =>
[_name] => imageTextImage
[_valid] => 1
)
[1] => Array
(
[ID] => 49
[key] => field_image_text_text
[label] => Text
[name] => imageTextText
[prefix] => acf
[type] => text
[value] =>
[menu_order] => 1
[instructions] =>
[required] => 0
[id] =>
[class] =>
[conditional_logic] => 0
[parent] => 51
[wrapper] => Array
(
[width] =>
[class] =>
[id] =>
)
[parent_layout] => layout_image_text
[default_value] =>
[placeholder] =>
[prepend] =>
[append] =>
[maxlength] =>
[_name] => imageTextText
[_valid] => 1
)
)
[min] =>
[max] =>
)
)
[button_label] => Element hinzufügen
[min] =>
[max] =>
[_name] => flex_content
[_valid] => 1
)
However, if I register the field via PHP these ID’s are 0 or a string and I wonder if this is a problem:
Array
(
[ID] => 0
[key] => field_main_content_flex_content
[label] => Content
[name] => flex_content
[prefix] => acf
[type] => flexible_content
[value] =>
[menu_order] => 0
[instructions] =>
[required] => 0
[id] =>
[class] =>
[conditional_logic] => 0
[parent] => group_main_content
[wrapper] => Array
(
[width] =>
[class] =>
[id] =>
)
[layouts] => Array
(
[layout_image_text] => Array
(
[key] => layout_image_text
[name] => image_text
[label] => Bild und Text
[display] => block
[sub_fields] => Array
(
[0] => Array
(
[ID] => 0
[key] => field_image_text_image
[label] => Bild
[name] => image
[prefix] => acf
[type] => image
[value] =>
[menu_order] => 0
[instructions] =>
[required] => 0
[id] =>
[class] =>
[conditional_logic] => 0
[parent] => field_main_content_flex_content
[wrapper] => Array
(
[width] =>
[class] =>
[id] =>
)
[return_format] => array
[preview_size] => medium
[library] => all
[min_width] =>
[min_height] =>
[min_size] =>
[max_width] =>
[max_height] =>
[max_size] =>
[mime_types] =>
[parent_layout] => layout_image_text
[_name] => image
[_valid] => 1
)
[1] => Array
(
[ID] => 0
[key] => field_image_text_text
[label] => Text
[name] => text
[prefix] => acf
[type] => text
[value] =>
[menu_order] => 1
[instructions] =>
[required] => 0
[id] =>
[class] =>
[conditional_logic] => 0
[parent] => field_main_content_flex_content
[wrapper] => Array
(
[width] =>
[class] =>
[id] =>
)
[default_value] =>
[placeholder] =>
[prepend] =>
[append] =>
[maxlength] =>
[parent_layout] => layout_image_text
[_name] => text
[_valid] => 1
)
)
[min] =>
[max] =>
)
)
[button_label] => Element hinzufügen
[min] =>
[max] =>
[_name] => flex_content
[_valid] => 1
)
Thanks for a quick feedback on these questions, and thanks also for your great plugin. 🙂
Hi, I’m trying to add an accordion to this custom page builder but i cant get it to work. Basically i have added open and closing accordion fields to the json file and each has a title and a wysiwyg editor, but it breaks my site when i try to use it.
json code:
[
{
"key": "group_553b8b2752aba",
"title": "Page Builder",
"fields": [
{
"key": "field_553b8b4fc8c3b",
"label": "Page Sections",
"name": "acf_page_builder",
"type": "flexible_content",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"button_label": "Add Section",
"min": "",
"max": "",
"layouts": [
{
"key": "56c0e6afec566",
"name": "banner",
"label": "Banner Image",
"display": "block",
"sub_fields": [
{
"key": "field_56c0e6efec56d",
"label": "Contained",
"name": "contained",
"type": "true_false",
"instructions": "",
"required": 0,
"conditional_logic": [
[
{
"field": "field_56c0a959e8e90",
"operator": "==",
"value": "1"
}
]
],
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"message": "Place in a container?",
"default_value": 0
},
{
"key": "field_56c0e712ec56e",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": [
[
{
"field": "field_56c0e6efec56d",
"operator": "==",
"value": "1"
}
]
],
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_56c0e6c8ec56c",
"label": "Image",
"name": "image",
"type": "image",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "url",
"preview_size": "medium",
"library": "all",
"min_width": "",
"min_height": "",
"min_size": "",
"max_width": "",
"max_height": "",
"max_size": "",
"mime_types": ""
},
{
"key": "field_56c0f2dcf1e39",
"label": "Text",
"name": "use_text",
"type": "true_false",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"message": "Place text over image?",
"default_value": 0
},
{
"key": "field_56c0f2b0f1e38",
"label": "Text on Top of Image",
"name": "text_on_image",
"type": "wysiwyg",
"instructions": "",
"required": 0,
"conditional_logic": [
[
{
"field": "field_56c0f2dcf1e39",
"operator": "==",
"value": "1"
}
]
],
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"tabs": "all",
"toolbar": "full",
"media_upload": 0
}
],
"min": "",
"max": ""
},
{
"key": "554a765bd3324",
"name": "button",
"label": "Button",
"display": "row",
"sub_fields": [
{
"key": "field_554a777fd3328",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_554a7667d3325",
"label": "Button Text",
"name": "button_text",
"type": "text",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_554a7684d3326",
"label": "Page Linking",
"name": "link_to_page",
"type": "select",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"choices": {
"anchor": "ID Anchor",
"external": "External Link",
"internal": "Internal Link"
},
"default_value": [],
"allow_null": 0,
"multiple": 0,
"ui": 0,
"ajax": 0,
"placeholder": "",
"disabled": 0,
"readonly": 0
},
{
"key": "field_55aff9e1ee51e",
"label": "Anchor",
"name": "button_anchor",
"type": "text",
"instructions": "",
"required": 1,
"conditional_logic": [
[
{
"field": "field_554a7684d3326",
"operator": "==",
"value": "anchor"
}
]
],
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "#",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_554a77f8d332b",
"label": "External Link",
"name": "external_link",
"type": "text",
"instructions": "",
"required": 1,
"conditional_logic": [
[
{
"field": "field_554a7684d3326",
"operator": "==",
"value": "external"
}
]
],
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_554a77c9d332a",
"label": "Internal Link",
"name": "internal_link",
"type": "page_link",
"instructions": "",
"required": 1,
"conditional_logic": [
[
{
"field": "field_554a7684d3326",
"operator": "==",
"value": "internal"
}
]
],
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"post_type": [],
"taxonomy": [],
"allow_null": 0,
"multiple": 0
}
],
"min": "",
"max": ""
},
{
"key": "5540bf0259b1d",
"name": "content_grid",
"label": "Content Columns",
"display": "block",
"sub_fields": [
{
"key": "field_56c0b470864df",
"label": "IMPORTANT",
"name": "",
"type": "message",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"message": "<p style=\"color: red;\">This section uses <a href=\"http:\/\/getbootstrap.com\/\" target=\"_blank\">Bootstrap<\/a> columns. Bootstrap divides the page width by columns in divisions of 12. So for 2 columns use width col-sm-6, for 3 columns use width col-sm-4, and so on. In most cases 'Offset' should be set to 0.<\/p>",
"new_lines": "wpautop",
"esc_html": 0
},
{
"key": "field_554909228473a",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_56c0b485864e0",
"label": "Wrapper Class",
"name": "wrapper_class",
"type": "text",
"instructions": "i.e. col-sm-4 col-sm-offset-4",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_5540bf1159b1e",
"label": "Content Columns",
"name": "content_columns",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"collapsed": "",
"min": 1,
"max": 4,
"layout": "table",
"button_label": "Add Columns",
"sub_fields": [
{
"key": "field_5540c0bb59b1f",
"label": "Content",
"name": "content",
"type": "wysiwyg",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": 70,
"class": "",
"id": ""
},
"default_value": "",
"tabs": "all",
"toolbar": "full",
"media_upload": 1
},
{
"key": "field_554a5878c9372",
"label": "Width",
"name": "width",
"type": "number",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": 15,
"class": "",
"id": ""
},
"default_value": 3,
"placeholder": "",
"prepend": "col-sm-",
"append": "",
"min": 1,
"max": 12,
"step": 1,
"readonly": 0,
"disabled": 0
},
{
"key": "field_554a57bbc9370",
"label": "Offset",
"name": "offset",
"type": "number",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": 15,
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "col-sm-offset-",
"append": "",
"min": 0,
"max": 12,
"step": 1,
"readonly": 0,
"disabled": 0
}
]
}
],
"min": "",
"max": ""
},
{
"key": "553b90972ce3e",
"name": "gallery",
"label": "Gallery",
"display": "row",
"sub_fields": [
{
"key": "field_553bd89149bd2",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_56c0ef638f980",
"label": "Images per Row",
"name": "images_per_row",
"type": "number",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": 4,
"placeholder": "",
"prepend": "",
"append": "",
"min": 2,
"max": 6,
"step": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_553b90972ce3f",
"label": "Images",
"name": "images",
"type": "repeater",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"collapsed": "",
"min": 1,
"max": 8,
"layout": "table",
"button_label": "Add Image",
"sub_fields": [
{
"key": "field_553bd41f82d1e",
"label": "Image",
"name": "image",
"type": "image",
"instructions": "",
"required": 1,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"return_format": "url",
"preview_size": "thumbnail",
"library": "all",
"min_width": "",
"min_height": "",
"min_size": "",
"max_width": "",
"max_height": "",
"max_size": "",
"mime_types": ""
},
{
"key": "field_553bd45b82d1f",
"label": "Title",
"name": "title",
"type": "text",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_553bd48582d20",
"label": "Caption",
"name": "caption",
"type": "text",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
}
]
}
],
"min": "",
"max": ""
},
{
"key": "561538dcc6acb",
"name": "raw_html",
"label": "Raw HTML",
"display": "row",
"sub_fields": [
{
"key": "field_56c0eb7227216",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_561538e6c6acc",
"label": "HTML",
"name": "html",
"type": "textarea",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"maxlength": "",
"rows": "",
"new_lines": "",
"readonly": 0,
"disabled": 0
}
],
"min": "",
"max": ""
},
{
"key": "561538dcw4334t",
"name": "accordion_row",
"label": "Accordion Row",
"display": "block",
"sub_fields": [
{
"key": "field_56c0ebgdtgs",
"label": "accordion-open",
"name": "",
"type": "accordion",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"open": 0,
"multi_expand": 0,
"endpoint": 0,
},
{
"key": "field_56c0eb72strgd",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_553bd45b2twf",
"label": "Title",
"name": "accordion-title",
"type": "text",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"placeholder": "",
"prepend": "",
"append": "",
"maxlength": "",
"readonly": 0,
"disabled": 0
},
{
"key": "field_553b8ce8yb45rty",
"label": "Content",
"name": "content",
"type": "wysiwyg",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"tabs": "all",
"toolbar": "full",
"media_upload": 1
},
{
"key": "field_56c0ebgdwc3f5",
"label": "accordion-close",
"name": "",
"type": "accordion",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"open": 0,
"multi_expand": 0,
"endpoint": 1,
},
],
"min": "",
"max": ""
},
{
"key": "553b8cd6dbe66",
"name": "wysiwyg",
"label": "Content Editor",
"display": "block",
"sub_fields": [
{
"key": "field_553bc590fbc55",
"label": "Background Colour",
"name": "bg",
"type": "color_picker",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": ""
},
{
"key": "field_553b8ce8c8c3c",
"label": "Content",
"name": "content",
"type": "wysiwyg",
"instructions": "",
"required": 0,
"conditional_logic": 0,
"wrapper": {
"width": "",
"class": "",
"id": ""
},
"default_value": "",
"tabs": "all",
"toolbar": "full",
"media_upload": 1
}
],
"min": "",
"max": ""
}
]
}
],
"location": [
[
{
"param": "post_type",
"operator": "==",
"value": "post"
}
],
[
{
"param": "page_template",
"operator": "==",
"value": "page-templates\/full-width.php"
}
]
],
"menu_order": 0,
"position": "normal",
"style": "default",
"label_placement": "top",
"instruction_placement": "label",
"hide_on_screen": [
"the_content"
],
"active": 1,
"description": ""
}
]
PHP:
<?php
Class ACF_Page_Builder {
/**
* Check if Advanced Custom Fields is Active
* @var (Boolean)
*/
private $acf_active;
/**
* Check if Simple Contact Forms is Active
* @var (Boolean)
*/
private $scf_active;
/**
* The final HTML to return with the section data inluded
* @var String
*/
private $html;
/**
* Formats that can be used in the acfs_add_support and acfs_remove_support functions
* @var Array
*/
public $supported_formats;
/**
* Variable to declare whether we should use Bootstrap or not
* @var Boolean
*/
private $use_bs;
/**
* Constructor of the class. Sets some default values
*/
function __construct() {
include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
$this->acf_active = is_plugin_active( 'advanced-custom-fields/acf.php' ) || is_plugin_active( 'advanced-custom-fields-pro/acf.php' );
$this->scf_active = is_plugin_active( 'simple-contact-forms/simple-contact-forms.php' );
$this->supported_formats = array('post_type', 'page_template');
$this->use_bs = function_exists('get_field') ? get_field('acfpb_use_bootstrap') : false;
}
/**
* Enqueue the styles and scripts for the public
*/
public function enqueuePublic() {
wp_enqueue_style( 'acfpb-public', plugin_dir_url( __FILE__ ) . '../public/css/acfpb_styles.css', false, NULL, 'all' );
}
/**
* Enqueue the styles and scripts for the admin
*/
public function enqueueAdmin() {
}
/**
* Retrieves all the section HTML
* @param String $name The slug used for the sections. Is 'sections' by default
* @return String The final HTML
*/
public function getSectionsHTML( $name, $post_id ) {
if( !$this->acf_active ) return '';
if( have_rows( $name, $post_id ) ):
$s = 1;
$this->html = '<div id="acfpb_sections">';
while ( have_rows( $name, $post_id ) ) : the_row();
$layout = get_row_layout();
if( method_exists(get_class(), 'getSection_' . $layout ) ) :
$id = 'section_' . $s;
$class = 'acfpb_section section-' . $layout;
$style = get_sub_field('bg') ? 'background-color:' . get_sub_field('bg') : '';
$contained = (boolean) get_sub_field('contained', false);
if( !$this->use_bs && $contained ) $contained = false;
$wrapper = get_sub_field('wrapper_class');
$this->html .= '<div id="' . $id . '" class="' . $class . '" style="' . $style . '"><div class="sectionwrap">';
if( $contained ) $this->html .= '<div class="container">';
if( $contained ) $this->html .= '<div class="row">';
if( $wrapper !== '' ) $this->html .= '<div class="' . $wrapper . '">';
$this->html .= $this->{'getSection_' . $layout}();
if( $wrapper !== '' ) $this->html .= '</div>'; // Wrapper finish
if( $this->use_bs ) $this->html .= '<div class="clearfix"></div>';
if( $contained ) $this->html .= '</div>'; // Row finish
if( $contained ) $this->html .= '</div>'; // Container finish
$this->html .= '</div></div>'; // Section finish
$s++;
endif;
endwhile;
$this->html .= '</div>'; // Main Wrapper finish
return $this->html;
else :
return '';
endif;
}
/**
* Admin function to add the fields to wordpress. Also figures out where to show them based on the acfs_add_support and acfs_remove_support functions
*/
public function addFieldsToWP() {
if( !$this->acf_active ) return false;
if( function_exists('acf_add_local_field_group') ) {
// Get the exported field data
$json = file_get_contents( plugin_dir_path(__FILE__) . '../admin/acf-fields.json' );
$json_to_php = json_decode( $json, true );
$acf_fields_array = $json_to_php[0]['fields'];
// Check if SCF is included or leave it out of the list of fields if not
if( !$this->scf_active ) {
foreach ($acf_fields_array[1]['layouts'] as $key => $data) {
if( $data['name'] === 'simple_contact_forms' ) {
unset( $acf_fields_array[1]['layouts'][$key] );
break;
}
}
}
// Create the rest of the field group
$meta = array(
'key' => 'group_553b8b2752aba_pb10192283',
'title' => 'Page Builder',
'fields' => $acf_fields_array,
'menu_order' => 10,
'position' => 'normal',
'style' => 'default',
'label_placement' => 'top',
'instruction_placement' => 'label',
'hide_on_screen' => array (),
'location' => array(),
'active' => 1,
'description' => '',
);
// Filter to get the locations
$location = apply_filters( 'acfpb_set_locations', array() );
$l = 0;
foreach ($this->supported_formats as $format) {
if( !isset($location[$format]) || empty($location[$format]) ) continue;
$meta['location'][$l] = array();
foreach ($location[$format] as $place) {
$meta['location'][$l][] = array(
'param' => $format,
'operator' => '==',
'value' => $place,
);
$l++;
}
}
acf_add_local_field_group($meta);
}
}
/**
* Get the Banner section.
* @return String Final string of this section
*/
private function getSection_banner() {
$class = $this->use_bs ? 'img-responsive' : '';
$html = '<div class="banner-holder">';
$html .= '<img src="' . get_sub_field('image') . '" class="' . $class . '" />';
if( get_sub_field('use_text') ) $html .= '<div class="acfpb-hover-text">' . get_sub_field('text_on_image') . '</div>';
$html .= '</div>';
return $html;
}
/**
* Get the button section.
* @return String Final string of this section
*/
private function getSection_button() {
$class = get_sub_field('button_class');
$text = get_sub_field('button_text');
switch ( get_sub_field('link_to_page') ) {
case 'anchor':
$href = '#' . get_sub_field('button_anchor');
break;
case 'external':
$href = get_sub_field('external_link');
break;
case 'internal':
$href = get_sub_field('internal_link');
break;
default:
$href = '#';
break;
}
$html = '<a href="' . $href . '" class="' . $class . '">' . $text . '</a>';
return $html;
}
/**
* Get the Content Grid section.
* @return String Final string of this section
*/
private function getSection_content_grid() {
$blocks = get_sub_field('content_columns');
$html = '';
if( count($blocks) > 0 ) :
foreach($blocks as $block) {
$html .= '<div class="col-sm-' . $block['width'] . ' col-sm-offset-' . $block['offset'] . '">';
$html .= $block['content'];
$html .= '</div>';
};
endif;
return $html;
}
/**
* Get the Gallery section.
* @return String Final string of this section
*/
private function getSection_gallery() {
$images = get_sub_field('images');
$html = '';
switch ( get_sub_field('images_per_row') ) {
case '2':
$first_class = 'col-sm-offset-2';
$class = 'col-sm-4';
break;
case '3':
$first_class = '';
$class = 'col-sm-4';
break;
case '5':
$first_class = 'col-sm-offset-1';
$class = 'col-sm-2';
break;
case '6':
$first_class = '';
$class = 'col-sm-2';
break;
default:
$first_class = '';
$class = 'col-sm-3';
break;
}
if( count($images) > 0 ) :
$i = 1;
foreach($images as $item) {
if( $i === 1 ) $class .= ' ' . $first_class;
$html .= '<div class="' . $class . '">';
$html .= '<img src="' . $item['image'] . '" class="' . ($this->use_bs ? 'img-responsive' : '') . '" />';
if( $item['title'] !== '' ) $html .= '<h4>' . $item['title'] . '</h4>';
if( $item['caption'] !== '' ) $html .= '<p>' . $item['caption'] . '</p>';
$html .= '</div>';
$i++;
};
endif;
return $html;
}
/**
* Get the Raw HTML section.
* @return String Final string of this section
*/
private function getSection_raw_html() {
$html = get_sub_field('html');
return $html;
}
/**
* Get the Simple Contact Forms section.
* @return String Final string of this section
*/
private function getSection_simple_contact_forms() {
if( !function_exists('simple_contact_form') ) return '';
$options = array();
if( get_sub_field('form_title') !== '' ) $options['form_title'] = get_sub_field('form_title');
if( get_sub_field('button') == true ) {
$options['button'] = true;
$options['form_collapsed'] = true;
if( get_sub_field('btn_text') !== '' ) $options['btn_text'] = get_sub_field('btn_text');
}
if( get_sub_field('email_subject') !== '' ) $options['email_subject'] = get_sub_field('email_subject');
$options['return'] = true;
$html = simple_contact_form( $options );
return $html;
}
/**
* Get the WYSIWYG section.
* @return String Final string of this section
*/
private function getSection_wysiwyg() {
$html = get_sub_field('content');
return $html;
}
/**
* Get the Accordion section.
* @return String Final string of this section
*/
private function getSection_accordion_row() {
$blocks = get_sub_field('accordion_row');
$html = '';
if( count($blocks) > 0 ) :
foreach($blocks as $block) {
$html .= '<div class"accordion-title">';
$html .= $block['accordion-title'];
$html .= '</div>';
$html .= '<div class"accordion-content">';
$html .= $block['content'];
$html .= '</div>';
};
endif;
return $html;
}
}