Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using get_terms() seems to break editing experience of dynamic block #8038

Closed
carrieforde opened this issue Jul 18, 2018 · 2 comments
Closed
Labels
[Type] Help Request Help with setup, implementation, or "How do I?" questions.

Comments

@carrieforde
Copy link

Describe the bug
Using get_terms() within a dynamic block's PHP seems to break the editing experience for the page on which the block lives.

This is what I expect to see when I try to edit the page on which this block lives:
Testimonial page edit screen

Instead, I am redirected to a singular testimonial edit screen:
Testimonial page edit screen

I have the following code to render a block in PHP:

/**
 * Build the markup for the testimonial tabs.
 * 
 * @param array $attributes The attributes passed from the editor.
 * @return string The markup.
 */
function fdr_content_blocks_testimonial_tabs( $attributes ) {

	$terms = get_terms( array(
		'taxonomy'   => 'fdrcf-testimonial-category',
		'hide_empty' => true,
	) );

	if ( empty( $terms ) || is_wp_error( $terms ) ) {
		return null;
	}

	ob_start();

	?>

	<div class="tabs">
		<div class="tabs__navigation">
			<?php foreach ( $terms as $term ) : ?>
				<?php if ( $term->term_id === $attributes['category'] ) : ?>
					<button id="<?php echo esc_attr( $term->slug ); ?>" class="tabs__button tabs__button--first tabs__button--active" role="tab" aria-selected="false" aria-controls="<?php echo esc_attr( $term->slug ); ?>-panel" tabindex="-1"><?php echo esc_html( $term->name ); ?></button>
				<?php else : ?>
					<button id="<?php echo esc_attr( $term->slug ); ?>" class="tabs__button" role="tab" aria-selected="false" aria-controls="<?php echo esc_attr( $term->slug ); ?>-panel" tabindex="-1"><?php echo esc_html( $term->name ); ?></button>
				<?php endif; ?>
			<?php endforeach; ?>
		</div>

		<?php foreach ( $terms as $term ) : ?>
			<div id="<?php echo esc_attr( $term->slug ); ?>-panel" class="tabs__panel" role="tabpanel" aria-labelledby="<?php echo esc_attr( $term->slug ); ?>" hidden="" tabindex="0">
				<?php get_posts_by_tax( $term->term_id ); ?>
			</div>
		<?php endforeach; ?>
	</div>

	<?php

	return ob_get_clean();
}

I have tried commenting out and reimplementing pieces of code to isolate the issue, and it seems like Gutenberg falls over because of the get_terms() call.

In case my actual query to get the posts is breaking my experience, here is that function:

/**
 * Get testimonials by term id.
 *
 * @param int $term_id The term being queried.
 */
function get_posts_by_tax( $term_id = 0 ) {

	$defaults = array(
		'post_type'      => 'fdrcf-testimonial',
		'posts_per_page' => 6,
		'tax_query'      => array(
			array(
				'taxonomy' => 'fdrcf-testimonial-category',
				'field'    => 'term_id',
				'terms'    => '',
			),
		),
	);
	$args = wp_parse_args( $args, $defaults );

	$post = array(
		'post_type'      => 'fdrcf-testimonial',
		'posts_per_page' => 6,
		'tax_query'      => array(
			array(
				'taxonomy' => 'fdrcf-testimonial-category',
				'field'    => 'term_id',
				'terms'    => $term_id,
			),
		),
	);

	$posts = new WP_Query( $post );

	if ( $posts->have_posts() ) {

		while ( $posts->have_posts() ) {

			$posts->the_post();

			$title = get_the_title();
			$title = explode( ' ', $title );

			$initials  = substr( $title[0], 0, 1 );
			$initials .= substr( $title[1], 0, 1 );

			$date = get_post_meta( get_the_ID(), 'testimonial_date', true );

			?>

			<article class="testimonial">
				<span class="testimonial__initials"><?php echo esc_html( $initials ); ?></span>

				<div class="testimonial__wrapper">
					<span class="star-rating"><?php display_stars(); ?></span>
					<?php echo the_content(); ?>
					<span class="testimonial__byline">&ndash;<?php echo get_the_title() . ', ' . esc_html( $date ); ?></span>
				</div>
			</article>

			<?php
		}
	}

	wp_reset_postdata();
}

To Reproduce
Steps to reproduce the behavior:

  1. Implement a dynamic block that uses get_terms()
  2. Add it to a page.
  3. Try to edit the page and see if you are taken to the wrong edit screen.

Expected behavior
When I edit my Testimonials page, I expect to be taken to the edit screen for the page, not to the edit screen for a single testimonial.

Screenshots
See above

Desktop (please complete the following information):
n/a

Smartphone (please complete the following information):
n/a

Additional context

  • Please add the version of Gutenberg you are using in the description.
    • Latest plugin version
  • To report a security issue, please visit the WordPress HackerOne program: https://hackerone.com/wordpress.
@chrisvanpatten
Copy link
Contributor

Thanks for the report @carrieforde! I'd strongly bet it's not specifically due to get_terms(), but is in fact the post query function. Running the $posts->the_post(); function causes the global $post variable to be reset, and wp_reset_postdata() doesn't currently work due to a Core bug.

You have a few options:

  1. Iterate over the $posts->posts array directly and access the values directly (e.g. $post->post_title) rather than using the standard Loop functions
  2. Save the global $post before running your loop functions, then set it again after your loop. There's a good example here

Hope this helps!

[Related to #8035 and #7582.]

@designsimply designsimply added the [Type] Help Request Help with setup, implementation, or "How do I?" questions. label Jul 19, 2018
@carrieforde
Copy link
Author

Hi @chrisvanpatten! 👋

This seems to have done the trick. Super weird, but hey, I learned a thing! Thanks so much for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Type] Help Request Help with setup, implementation, or "How do I?" questions.
Projects
None yet
Development

No branches or pull requests

3 participants