[Resolved] How to add another field of text to a Post listing

Home Forums Support How to add another field of text to a Post listing

This topic contains 15 replies, has 2 voices, and was last updated by  David 5 days, 20 hours ago.

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #1196945

    Tim

    I have a list of posts with Title, Featured Image and Excerpt.

    How can I add another element or field of text to the list such as a Job Position.

    Thanks

    Tim

    #1197004

    David Customer Support

    Hi there,

    this requires Custom Fields and a little bit of custom development.

    Simplest method is to install Advanced Custom Fields plugin:

    https://www.advancedcustomfields.com/resources/displaying-custom-field-values-in-your-theme/

    Once you have a field registered you can use their get_field()function to display it:
    https://www.advancedcustomfields.com/resources/get_field/

    To show this in the WP Show Post loop.

    1. Create a new Hook Element.
    https://docs.generatepress.com/article/hooks-element-overview/

    2. Add your Custom field code eg.

    <?php
    $position = get_field( "yoir_custom_field_name" );
    if ( $position ) {
    	echo '<h4>Position: ' . $position . '</h4>';
    }
    ?>

    3. Select Hook > Custom Hook
    4. Add wpsp_after_content in the field available
    Tom provides a list of Hooks that WP Show Posts has here

    5. Check execute PHP
    6. Set Display Rules – Entire Site

    #1209263

    Tim

    Hi David

    Ah yes, ACF, I remember playing with that many years ago.

    Thank you for the advice and example.

    I decided to focus on the Post before the Post Listing.

    I created a field group “Staff Profile Fields” and then an Element “Staff Profile Element” with Hook after_entry_title for “Posts” that have category “Team”

    <div>
    <?php
    $position = get_field( "job_position" );
    if ( $position ) {
    	echo '<h2>' . $position . '</h2>';
    }
    $nationality = get_field( "nationality" );
    if ( $nationality ) {
    	echo '<p>Nationality: ' . $nationality . '</p>';
    }
    $qualification = get_field( "qualification" );
    if ( $qualification ) {
    	echo '<p>Qualification: ' . $qualification . '</p>';
    }
    $skills = get_field( "skills" );
    if ( $skills ) {
    	echo '<p>Skills: ' . $skills . '</p>';
    }
    $portrait = get_field( "portrait" );
    if ( $portrait ) {
    	echo '<img src=' . $portrait['url'] . '/>';
    }
    $description = get_field( "description" );
    if ( $description ) {
    	echo '<p>' . $description . '</p>';
    }
    $quote = get_field( "quote" );
    if ( $quote ) {
    	echo '<blockquote>' . $quote . '</blockquote>';
    }
    $citation = get_field( "citation" );
    if ( $citation ) {
    	echo '<cite>' . $citation . '</cite>';
    }	
    ?>
    <div>

    The Portrait renders for a moment but is then broken.

    The example on ACF site https://www.advancedcustomfields.com/resources/getting-started-with-acf/ differs in structure to the example of yours that I’m following.

    I intend to replicate the style that the standard WP Gutenberg generates, which is still displayed below the Element created above.

    What is the best practice code structure to use here ?

    Thanks

    Tim

    #1209374

    David Customer Support

    For that level of content i would be more inclined with the ACF structure.
    Looks like the lazy load plugin is messing with that image.

    #1210394

    Tim

    Hi David

    The Element code now looks like this, please tell me if I can improve on that in some way:

    <?php if( get_field('job_position') ): ?>
        <h2><?php the_field('job_position'); ?></h2>
    <?php endif; ?>
    
    <?php if( get_field('nationality') ): ?>
        <p>Nationality: <?php the_field('nationality'); ?></p>
    <?php endif; ?>
    
    <?php if( get_field('qualification') ): ?>
        <p>Qualification: <?php the_field('qualification'); ?></p>
    <?php endif; ?>
    
    <?php if( get_field('skills') ): ?>
        <p>Skills: <?php the_field('skills'); ?></p>
    <?php endif; ?>
    
    <div>
        <?php $portrait = get_field('portrait'); ?>
        <img src="<?php echo $portrait['url']; ?>" alt="<?php echo $portrait['alt']; ?>" />
    </div>
    
    <?php if( get_field('description') ): ?>
        <p><?php the_field('description'); ?></p>
    <?php endif; ?>
    
    <?php if( get_field('quote') ): ?>
        <blockquote><?php the_field('quote'); ?></blockquote>
    <?php endif; ?>
    
    <?php if( get_field('citation') ): ?>
        <cite><?php the_field('citation'); ?></cite>
    <?php endif; ?>

    All the elements display.

    What I would like to do now is make the necessary changes to style them in the standard wp format which you can see below the custom entry.

    Of particular note, the style required to float left the position, nationality, qualification, skills, and float right the portrait.

    What I wonder about here with the img is that from the page source it is missing all the media query type stuff that wp puts in with media elements. Do you know how I can get that back with my custom image field ?

    Also I notice the cite needs shoe horning into the blockquote somehow.

    #1210629

    David Customer Support

    Looks fine to me you have some closing PHP ?> followed immediately by an opening <?php – neither of which are strictly needed but i would leave em there as it keeps it cleaner to read and easier to shuffle about if needed.

    You could copy the block markup eg. the Media Text block:

    <div class="wp-block-media-text alignwide has-media-on-the-right is-vertically-aligned-top">
    
        <figure class="wp-block-media-text__media">
            <?php $portrait = get_field('portrait'); ?>
            <img src="<?php echo $portrait['url']; ?>" alt="<?php echo $portrait['alt']; ?>" />
        </figure>
    
        <div class="wp-block-media-text__content">
            
        <?php if( get_field('job_position') ): ?>
            <h2><?php the_field('job_position'); ?></h2>
        <?php endif; ?>
        
        <?php if( get_field('nationality') ): ?>
            <p>Nationality: <?php the_field('nationality'); ?></p>
        <?php endif; ?>
        
        <?php if( get_field('qualification') ): ?>
            <p>Qualification: <?php the_field('qualification'); ?></p>
        <?php endif; ?>
        
        <?php if( get_field('skills') ): ?>
            <p>Skills: <?php the_field('skills'); ?></p>
        <?php endif; ?>
    
        </div>
    </div>

    And for the quote:

    <?php if( get_field('quote') ): ?>
    <blockquote class="wp-block-quote">
    
        <p><?php the_field('quote'); ?></p>
    
        <?php if( get_field('citation') ): ?>
        <cite><?php the_field('citation'); ?></cite>
        <?php endif; ?>
    
    </blockquote>
    <?php endif; ?>
    #1211450

    Tim

    Hi David

    Thank you for the code. The method and example has helped me understand how to get to grips with future layout tasks.

    I noticed that I still needed to wrap it all in <div class="entry-content" itemprop="text"> ... </div>

    Do you know if there is a way to retain the srcset which seems to get lost using ACF ?

    I have also implemented the strategy you gave me above for the custom fields in wp show post lists, which seems to working well.

    Thanks

    Tim

    #1211732

    David Customer Support

    You can use the wp_get_attachment_image() function to output the image.

    ACF provides this doc info:
    https://www.advancedcustomfields.com/resources/image/#template-usage

    #1212633

    Tim

    Hi David

    Thanks for pointing out the example from ACF.

    I did try simply adding their code as is, replacing image with portrait for my case:

    <?php 
    $portrait = get_field('portrait');
    $size = 'full'; // (thumbnail, medium, large, full or custom size)
    if( $portrait ) {
        echo wp_get_attachment_image( $portrait, $size );
    }
    ?>

    But nothing was displayed. I suppose it shouldn’t since there is no HTML.

    So I also tried inserting where I thought it might need to go within the existing block:

        <figure class="wp-block-media-text__media">
            <?php $portrait = get_field('portrait');
    	      $size = 'full'; // (thumbnail, medium, large, full or custom size) ?>
            <img src="<?php echo $portrait['url']; ?>" alt="<?php echo $portrait['alt']; ?>" srcset="<?php echo wp_get_attachment_image( $portrait, $size ); ?>" />
        </figure>

    Whilst I don’t get errors, the rendered source shows nothing has been added to the srcset

    I have next to zero understanding of PHP, but I suppose I need to add ['srcset'] somewhere in that line of code, yet all the things I tried gave errors.

    Any ideas ?

    Thanks

    Tim

    #1212835

    David Customer Support

    Is your ACF Image filed using the Image ID return type ?
    If it is then your first block of code should be working.

    #1212847

    Tim

    Hi David

    Ah, well spotted, I hadn’t noticed the 3 radio button options. It was on the default Image Array. I’ve now set it to Image ID but now the image doesn’t render.

    I guess I need to modify this block and add wp_get_attachment_image for the ['url'] and ['alt'], but I’m not sure of the syntax.

        <figure class="wp-block-media-text__media">
            <?php $portrait = get_field('portrait');
    							$size = 'full'; ?>
            <img src="<?php echo $portrait['url']; ?>" alt="<?php echo $portrait['alt']; ?>" srcset="<?php echo wp_get_attachment_image( $portrait, $size ); ?>" />
        </figure>
    #1213116

    David Customer Support

    No – this code:

    <?php 
    $portrait = get_field('portrait');
    $size = 'full'; // (thumbnail, medium, large, full or custom size)
    if( $portrait ) {
        echo wp_get_attachment_image( $portrait, $size );
    }
    ?>

    I just tested this and it worked fine.
    If you remove any other code related to the ACF images. And test that code on its own for now. Then make sure to clear any caches – plugin and browser.

    #1218005

    Tim

    Hooray.

    Yes I think cache was playing games with me.

    So now I see that no HTML needs to be interspersed with that block of code and all the img, src, alt and srcset etc are programmatically added for me.

    Similarly, I discovered that the ACF Wysiwig Editor, my description, doesn’t need a surrounding <p> tag, otherwise an orphaned paragraph is introduced to the rendered source.

    <div class="entry-content" itemprop="text">
    	
    	<div class="wp-block-media-text alignwide has-media-on-the-right is-vertically-aligned-top">
        
    		<figure class="wp-block-media-text__media">
    			<?php 
    				$portrait = get_field('portrait');
    				$size = 'full'; // (thumbnail, medium, large, full or custom size)
    				if( $portrait ) {
        			echo wp_get_attachment_image( $portrait, $size );
    				}
    			?>
        </figure>
        
    		<div class="wp-block-media-text__content">
        	
    			<?php if( get_field('job_position') ): ?>
            <h2><?php the_field('job_position'); ?></h2>
        	<?php endif; ?>
        	
    			<?php if( get_field('nationality') ): ?>
            <p>Nationality: <?php the_field('nationality'); ?></p>
        	<?php endif; ?>
        
    			<?php if( get_field('qualification') ): ?>
            <p>Qualification: <?php the_field('qualification'); ?></p>
        	<?php endif; ?>
        
        	<?php if( get_field('skills') ): ?>
            <p>Skills: <?php the_field('skills'); ?></p>
        	<?php endif; ?>
    
        </div>
    	</div>
    	<?php if( get_field('description') ): ?>
        <?php the_field('description'); ?>
    	<?php endif; ?>
    
    	<?php if( get_field('quote') ): ?>
    
    	<blockquote class="wp-block-quote">
    
        <p><?php the_field('quote'); ?></p>
    
        <?php if( get_field('citation') ): ?>
        <cite><?php the_field('citation'); ?></cite>
        <?php endif; ?>
    
    	</blockquote>
    	<?php endif; ?>
    	
    </div>

    I thought I was done with this but then I realised I want the Media Text element to stack on mobile and crop the image to fill the column as can be done via the standard block.

    The stacking part was easy by just adding is-stacked-on-mobile:

    <div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile is-vertically-aligned-top">

    But when adding is-image-fill the image no longer renders:

    <div class="wp-block-media-text alignwide has-media-on-the-right is-stacked-on-mobile is-vertically-aligned-top is-image-fill">

    I guess that I need to add the additional style to the <figure> tag:

    <figure class="wp-block-media-text__media" style="background-image:url(https://domain.com/image-location.jpg);background-position:50% 50%">

    Please can you help me with the PHP to get the URL ?

    Thanks

    Tim

    #1218404

    David Customer Support

    I can’t see that being any benefit to your requirements , that method is fine when the image is ok to be cropped. But i am sure you don’t want to crop the persons portrait.

    Might be simpler to remove those classes and we add some CSS for the rows / columns.

    For example – change:

    <div class="wp-block-media-text alignwide has-media-on-the-right is-vertically-aligned-top">

    to

    <div class="team-header">

    change:

    <figure class="wp-block-media-text__media">

    to:

    <figure class="team-header-image">

    and:

    <div class="wp-block-media-text__content">

    to

    <div class="team-header-content">

    Then add this CSS:

    .team-header-image {
        margin-bottom: 2em;
    }
    .team-header-content {
        flex: 1 0 50%;
        padding-right: 20px;
        box-sizing: border-box ;
    }
    @media (min-width: 769px) {
        .team-header {
            display: flex;
            flex-direction: row-reverse 
        } 
    }
    #1220589

    Tim

    Hi David

    Yes your right it doesn’t make sense to crop these to the height of a potentially dynamic column height.

    Thank you for such persistent support.

    Tim

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic.