Support

Account

Home Forums Add-ons Repeater Field Repeater field for Sidebar Page Links

Solved

Repeater field for Sidebar Page Links

  • I have pages that belong to categories.

    Inside each page is a repeater field set up to display page links to other parts of the website like this:

    Page Link
    Page Link Name

    The page link is a dropdown list of every page in the website. The page links are to be displayed in the sidebar so they will be a different set of page links from page to page.

    The page category has an image field assigned to it using a custom field, and this field forms the image that will replace the title of the category on output in the sidebar.

    What I want to know is how can I output

    Page Link & Page Link Name (page_link & page_link_name)

    with the category image above each page link to show which category the page link belongs to. I also want all the page link categories to be displayed in alphabetical order, so that all links that belong to each category display grouped together.

    Lastly I’d like to apply an ID to the category images. The first category image above the first link should have a different ID to all the other Category Image ID’s which should all be the same. This is so I can control their display with CSS.

    note I am using this plugin https://wordpress.org/plugins/category-for-pages – I don’t have to use that particular plugin as there are others or if anyone knows how I could add this functionality without a plugin that would be great, not essential though.

  • What you’re looking to do is quite complex.

    First of all, it is not possible to directly order posts by a term. What you need to do is to get all of the terms, loop through the terms and get all of the posts in each term based on the list of links on the page.

    That’s

    
    get categories
       each category
          get posts using "post__in" query where the post_in value is derived from the list of links
          if there are posts in the category
             get the category image and display
             each post
                show link
    

    helpful links https://wordpress.stackexchange.com/questions/142268/order-posts-by-category-name, https://www.google.com/search?q=order+posts+by+category&oq=order+posts+by+category

  • ok well looking through some of the google search it looks like I am not the only one that has had trouble with this. I’m aware its complex. It looks like there might be a few things to go at though which may get me halfway there at least. I suspect I will have to come back here for more help though. Thank you so far as this looks like it might be useful.

  • Well got a couple of bits of code sort of working:

    Firstly this one which may be good for development further:

    <?php if ( is_active_sidebar( 'sidebar-1' )  ) : ?>
    	<aside id="secondary" class="sidebar widget-area" role="complementary">
    		<?php dynamic_sidebar( 'sidebar-1' ); ?>
    			
    			<?php $terms = get_terms( 'category' );
     if ( ! empty( $terms ) && ! is_wp_error( $terms ) ){
         echo '<ul>';
         foreach ( $terms as $term ) {
           echo '<li>' . $term->name . ' - ' . '<img src="' . get_field('category_image', $term->taxonomy . '_' . $term->term_id) . '"></li>';
            
         }
         echo '</ul>';
    	 
     } ?>

    This retrieves the category image for each category. I can build on that because I could apply the category image into a div background. This would hide the category image if there are no links to show beneath if I apply the image into the div as a background and the div doesn’t have a height.

    I just don’t know how to pull the posts in that would appear beneath each category heading.

    Then there is this:

    <?php 
    
        $args = array( 
            'post_type' => 'page','posts_per_page' => -1
        );
    
        $query = new WP_Query($args);   
        $q = array();
    
        while ( $query->have_posts() ) { 
    
            $query->the_post(); 
            
            $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';
    
            $categories = get_the_category();
    
            foreach ( $categories as $key=>$category ) {
    			
                $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    
    
            }
    
            $q[$b][] = $a; // Create an array with the category names and post titles
        }
    
        /* Restore original Post Data */
        wp_reset_postdata();
    
        foreach ($q as $key=>$values) {
            echo $key;
    
            echo '<ul>';
                foreach ($values as $value){
    				echo '<img src="';
    				the_field('category_image', 'category_4');
    				echo '">';
                    echo '<li>' . $value . '</li>';
                }
    		
            echo '</ul>';
        }
    
    ?>

    This lists a category image above each post. If you look at the code I am having to call a category id – the_field(‘category_image’, ‘category_4’);

    to get the image to display.

    This would mean the same category image would display for all categories which would be wrong. On the other hand this retrieves all posts and puts them under the correct category titles they should appear under.

    So if I could somehow combine the above two pieces of code I would be halfway there.

    Although I still have to find some way of choosing which pages display from each category under each heading in the sidebar. I was thinking perhaps set them all somehow as ‘false’ until chosen from each page in the admin from a custom field menu then set them as ‘true’ if chosen.

    Both examples of code can be viewed here:

    http://151.252.3.6/~lewishickeyplatf/wordpress/

    You will see Code 1 Example and Code 2 Example

    Code 1 being the first bit of code above and Code 2 being the second bit of code above.

  • I’ve attached a screenshot. I am just wondering if I can somehow pull all the posts from all categories from each category under their correct category image, but make them all false, so they don’t display until they are chosen from a repeater field in the admin with a Page Link field using the Advanced Custom Fields: Link Picker add on for ACF.

    So false until picked and the page is updated then true so they display.

  • Another way would be to utilise the ‘Custom Sidebar Links’ plugin which allows you to choose what is displayed from tickboxes.

  • this is kind of what i mean by true/false using conditional tags https://pippinsplugins.com/wordpress-conditional-tags-overview/

  • Ok I now have this which displays the category image and all the posts associated with the category beneath it `<?php $args = array (
    ‘orderby’ => ‘name’,
    ‘order’ => ‘ASC’,
    ‘hide_empty’ => true,
    );

    $terms = get_terms( ‘category’, $args );
    foreach ( $terms as $term ) {
    echo ‘<br />’;
    echo ” . ‘<img src=”‘ . get_field(‘category_image’, $term->taxonomy . ‘_’ . $term->term_id) . ‘”>’;
    $post_args = array (
    ‘category_name’ => $term->slug,
    ‘posts_per_page’ => ‘-1’,
    ‘no_found_rows’ => true
    );

    $query = new WP_Query( $post_args );

    while ( $query->have_posts() ) {
    $query->the_post(); ?>

    <br /><div class=”hidepost”><?php the_title(); ?></div>

    <?php }
    } ?>`

    What I now need is a way to show or hide the page links on a page by page basis.

    Anybody have any ideas how I might achieve this?

  • Hi James, I have resolved this…who says ACF can’t handle this sort of thing 😉

    I’ll post this on the forum as well just in case anyone wants to see it there. First things first, this is the code I ended up with and I will try to explain it:

    <?php $args = array (
        'orderby'    => 'name',
        'order'      => 'ASC',
        'hide_empty' => true,
    );
    
    $terms = get_terms( 'category', $args );
    foreach ( $terms as $term ) {
    	echo '<br />';
        echo '' . '<img src="' . get_field('category_image', $term->taxonomy . '_' . $term->term_id) . '">';
        $post_args = array (
            'category_name' => $term->slug,
            'posts_per_page'   => '-1',
            'no_found_rows' => true
        );
    
        $query = new WP_Query( $post_args );
    
        while ( $query->have_posts() ) {
            $query->the_post(); ?>
    
    		<br /><div class="hidepost page-id-<?php echo $post->ID; ?>"><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></div>
    
        <?php }
    } ?>

    In its simplest terms this code display a category image field created using ACF and all the pages assigned to the categories. Note these are pages, not posts!

    You will see in this code that I have applied <div class="hidepost page-id-<?php echo $post->ID; ?>"><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>">

    Firstly the hidepost class can be used in CSS to hide all the pages that are now loaded into every page sidebar in the site.

    You would just use:

    .hidepost {
    display:none;
    }

    in your stylesheet.

    Secondly we have a class named: page-id-<?php echo $post->ID; ?>

    This pulls in the page id class so you end up with something like page-id-10 which can be used to show or hide the page link something like:

    .page-id-10 {
    display:block!important;
    }

    You can of course do this from the stylesheet but I needed to go a step further and have the display of these pages controlled through the admin, which is where ACF came in use again.

    I created a repeater field named Sidebar Links with a field in the repeater called Page Link which utilises the Page Link Field Type.

    This would normally output a url which was no use in my case as I needed it to output the page ID of the Page Link. So I delved into the ACF plugin itself and edited fields>page_link.php (I have kept a backup of the original).

    In page_link.php find around line 603:

    // convert $post to permalink
    			if( is_object($post) ) {
    				
    				$post = get_permalink( $post );
    			
    			}

    In mine I changed it to:

    // convert $post to permalink
    			if( is_object($post) ) {
    				echo '.page-id-';
    				echo $post->ID;
    				echo '{';
    				echo 'display:block!important;';
    				echo '}';
    				$post = ( '' );
    			
    			}

    In my template I can now use:

    <?php 
    
    // check if the repeater field has rows of data
    if( have_rows('sidebar_links') ):
    
     	// loop through the rows of data
        while ( have_rows('sidebar_links') ) : the_row();
    	    
    	the_sub_field('page_link');
    
        endwhile;
    
    else :
    
        // no rows found
    
    endif;
    
    		?>

    which outputs something like .page-id-10 {display:block!important;}

    So if I want to control the display of each field dynamically I can now apply this code into the header.php template in the <head></head> section like this:

    <style>
    <?php 
    
    // check if the repeater field has rows of data
    if( have_rows('sidebar_links') ):
    
     	// loop through the rows of data
        while ( have_rows('sidebar_links') ) : the_row();
    	    
    	the_sub_field('page_link');
    
        endwhile;
    
    else :
    
        // no rows found
    
    endif;
    
    		?></style>

    The above allows me to display the page link if it is selected using the ‘edited’ page link field.

Viewing 9 posts - 1 through 9 (of 9 total)

The topic ‘Repeater field for Sidebar Page Links’ is closed to new replies.