• Hi,

    I am trying to build ‘team’ page where the goal is to display the photo of the person and a bio about them. I was told to create a post for each person in a category called ‘team’ and use an array to display the pictures in a carousel and when you click the persons picture it would display the bio at the bottom.

    I don’t know where to start with this apart from creating a category, featured image for each post is the persons picture and the content is their bio.

    Any help would be much appreciated..

    Category name: team
    Display via tabbed/carousel array on different page.

    Thanks

Viewing 3 replies - 1 through 3 (of 3 total)
  • First decide how you want the html to function.

    Are you going to create inline or inline-block span elements or li elements in some ul element so they will get horizontally displayed?

    I don’t know how to do anything called a ‘carousel’ but I think you just want a horizontal list?

    Then when you have that list, how are you going to load the bio? Are you going to use JavaScript in the onClick handler for the images?

    If you use pure HTML for that, it will require loading the entire team page with a new parameter each time. With JavaScript, you can load that bio dynamically in the browser.

    But there are primarily two ways of doing that:

    1. load all bios in one go by having the page template for your team page (or the category template for your team category) do a WP_Query query on all of the posts (pretty much default behaviour for a category template) while creating unique IDs (possibly using array syntax) for identical HTML tags that contain the bio… and then using JavaScript to hide/unhide the various #ids.
    2. use AJAX calls to query a script that outputs a bit of HTML containing the bio, which is then loaded dynamically into the element that you have designated for showing the bio.

    Personally I think the latter is a prettier solution but the former is probably easier at first sight.

    In either case, I suggest using jQuery for doing it.

    This is simple jQuery syntax for hiding an element and showing another:

    $( "#elementid" ).css( "display", "none" );
    $( "#elementid" ).css( "display", "inherited" );

    This is simple jQuery syntax for setting the contents of an element:

    $( "#elementid" ).html( javascriptVariable );

    This is simple jQuery syntax for loading a PHP result into an element:

    $( "#elementid" ).load( "obtain-bio.php?id=NNN" );

    The benefits of method 1 is that after the page has loaded, it is very responsive. With method 2, each click on a picture will cause new data to be requested from the server.

    I do not know what a “featured image” is and I would like to have something like that myself because I often include images that I want displayed as thumbnails in my excerpts in my posts, but supposing that you just randomly include one(1) image in each post, you could simply extract or filter that image by doing:

    if (preg_match('@<img .*?(/>|</img>)@i', $post->post_content, $m) {
        $img =& $m[0];
        // do something with the image
    } else {
        // display error about missing image
    }

    And to remove it from the contents so only the bio remains:

    $bio = preg_replace('@<img .*?(/>|</img>)@i', '', $post->post_content);

    This may leave a <p></p> paragraph if WP had inserted that. But it usually does so in a later stage. In fact, it only does so when you use the_content() to display your post. You can apply any filter before that by using the 'post_content' filter.

    But there is also a feature in WP called “attachments”. When you insert an image into a post, it adds that image as an attachment for that post, which is a child of the post in the parent-child hierarchy for posts. If you then remove the image link from the post content itself, the attachment remains.

    So, you can also skip this filtering and just query the attachment when you want the image for a post:

    $attachments = get_posts("post_type=attachment&numberposts=1&post_parent={$post->ID}");
    if ($attachments) {
        $img = wp_get_attachment_image( $attachments[0]->ID, 'full' );
        // display the image in your container element
        echo "<li>$img</li>";
    }

    The reason I do not really like this solution is because I don’t really feel to be in control of these attachments. They are weird parent-child objects existing as separate ‘post’ objects. I have no idea what their post content is (how is that defined?) and in fact their content is not defined but the link to the image exists in the “guid” field. Why someone would define something as a “post” object while then having no contents is beyond me.

    The hierarchy thus described also seems to be limited to just two levels which means the attachments could simply have been described as objects in some “attachments” array defined by relationships described in a new (additional) relationships table or (if you want strict hierarchy) simply as the parents of those attachments objects in a new attachment table.

    There is not actually a way (in 3.9.1) to edit these ‘attachment’ links all you can do is delete the object (the post object of type ‘attachment’ that is shown in the media library). It also means you cannot attach the same file to multiple posts which means I (in my own situation) will have to keep uploading the same image file again and again just so they can properly be ‘attached’ to the posts I want them for.

    Which means I will probably be writing my own plugin using custom post fields (metadata) linking to unattached media library files instead of having them as child objects for single individual posts.

    Essentially, for your (YST) use case it doesn’t matter, I just don’t like using this parent-child link to obtain the reference to the files, because if the implementation for this changes at some future moment, your code will cease working and because of that consideration I feel it is better to depend on your own solution which is simply the inclusion of an <img src=”…” /> link into your post content.

    That way your individual posts (if you provide a way to access them) still show the image (if you want that, you have to account for that).

    But since you will exclude this category from normal post listings, that will not really be a consideration I would think.

    So I would strongly suggest to just use this solution:

    For the code that generates the ‘carousel’ just extract the <img> tag like this:

    if (preg_match('@<img .*?(/>|</img>)@i', $post->post_content, $m) {
        $img =& $m[0];
        echo "<li>$img</li>\n";
    }

    You need onClick events for these images or their containing elements. Register them using:

    $('#team-img-N').on('click',
        function (e) {
            changeBio(e.target.id);
        });

    Then you have another JavaScript function “changeBio” that takes the element ID of your image tag (for instance) and uses it to effectuate the change you need according to the method you choose.

    If, for example, all your elements are named “#team-pic-NNN” where NNN is the number of the post (its ID really in the WordPress database) you can use it to easily reference either the elements you want to hide/unhide or the URL of the bio snippet you want to load.

    So you use a simple javascript function like substr to take the number out of the ID:

    function changeBio(element) {
        id = element.substr(10);
        // do the hide/unhide, or the load
    }

    Then you need PHP to put those element IDs in some tags. It would seem easiest to give them to the <li> tags I’ve used as an example.

    echo "<li>$img</li>\n"; becomes echo "<li id=\"#team-pic-{$post->ID}\">$img</li>\n";

    After that you just need to ensure proper CSS styling and whatnot.

    You could use a WP_Query loop to process all the posts in a category. Probably easiest is to just do a get_posts() with the required parameters and then looping over them with a foreach.

    If you go the hide/unhide route you just iterate the array you get again when you create all of the (hidden) elements. If the hiding (display: none) of those elements does not disrupt the page flow (because their container element has a fixed size and uses scroll bars, or perhaps it doesn’t matter) the hiding/unhiding should not be a big deal… I think.

    So I think these are all the fundamental elements you need.

    This is everything you need for the most basic solution.

    For the AJAX retrieval route you just need a small PHP file that loads the WP environment:

    <?php
    
    require_once( dirname(__FILE__) . '/../wp-load.php' );
    
    ?>

    If you put your obtain-bio.php script in /ajax/obtain-bio.php that snippet would load the WP environment provided those WP PHP files are in the website root.

    Then all you need is to return the contents of the post excluding the image:

    $param_id = $_GET['id'];
    if ($param_id) {
        $post = get_post($param_id);
        if ($post && $post->post_status == 'publish') {
            // we want the post_content to be processed the way WP likes to do
            // but first remove the image
            $bio = preg_replace('@\n?<img .*?(/>|</img>)\n?@i', '', $post->post_content);
            // also removes a potential leading and trailing newline
            // apply default WP filters
            $bio = apply_filters('the_content', $bio);
            // echo raw text
            echo $bio;
        } else {
            echo "<p>Error in your script. $param_id is not a valid post ID in this WordPress installation.</p>";
        }
    } else {
      echo "<p>This script requires a post-ID parameter</p>";
    }

    I’ve tested this last script and it works like a charm. Obviously it will return every valid published post, not just ‘team’ category posts.

    So there you have it:

    • a HTML list containing the pictures
    • each picture element gets assigned a unique ID
    • for each such element a JavaScript event handler is assigned (the same code snippet for all elements)
    • the event handler calls a function that takes the element ID and uses it to change/load the bio for the required ID
    • the PHP code for the team page generates all those elements and IDs after obtaining a WP_Post array of the suitable posts
    • the image to display is extracted from the content of each post using a bit of regular expression matching
    • the remaining content to display has the image removed using a bit of regular expression replacing
    • you can choose whether to load everything at once or do lazy loading

    I don’t think there is much more to it. I believe you have all or most of the code you need, and what remains will be easy to adjust. You will have to learn how to load the jQuery library and how to insert JavaScript snippets that can get executed. That “changeBio” function you would place in the HTML <head> tag. The jQuery code to set the “click”-event handler can probably be expanded to set it for all required elements at once. If you need more help, let me know, but I expect you to take what you have now and try to make it work yourself.

    Good luck! You will need it :).

    First question – Do you have a blog/news on the site? If yes, do you want the team members to show up within the list of blog posts as they’re going to the way you have done it. Personally I would use a custom post type for team members, as they’re not blog articles, so should be handled separately.

    Register a new post type (this goes in functions.php of your theme):

    if( ! function_exists( 'my_custom_post_type_team' ) ) {
    
    	function my_custom_post_type_team()
    	{
    		$labels = array(
    			'name' => _x( 'Team', 'post type general name' ),
    			'singular_name' => _x( 'Team', 'post type singular name' ),
    			'add_new' => __( 'Add New' ),
    			'add_new_item' => __( 'Add New Member' ),
    			'edit_item' => __( 'Edit Team Member' ),
    			'new_item' => __( 'New Team Member' ),
    			'all_items' => __( 'All Members' ),
    			'view_item' => __( 'View Team Member' ),
    			'search_items' => __( 'Search Team' ),
    			'not_found' =>  __( 'No team members found' ),
    			'not_found_in_trash' => __( 'No team members found in Trash' ),
    			'parent_item_colon' => '',
    			'menu_name' => 'Team'
    		);
    
    		$args = array(
    			'labels' => $labels,
    			'public' => false,
    			'show_ui' => true,
    			'capability_type' => 'post',
    			'hierarchical' => false,
    			'supports' => array( 'title', 'editor', 'thumbnail', 'page-attributes' ),
    			'menu_position' => 21
    		);
    
    		register_post_type( 'team', $args );
    	}
    	add_action( 'init', 'my_custom_post_type_team' );
    }

    This will register a custom post type for “team” members, you’ll notice within your Admin panel a new tab labeled ‘Team’. This post type is not public (it will not have it’s own page), if you need to make it public , set ‘public’ to true.

    Next, you’ll need to “get” the data from the database, you can do this with WP_Query, the code would look something like this (although you’ll have to tweak it to get what you need). This code goes into one of your theme files (wherever you want the carousel output). Alternatively you can create a shortcode with this in, but i’ll leave you to figure that out.

    $q = new WP_Query( array(
    	'post_type' => 'team',
    	'posts_per_page' => -1,
    ) );
    
    if( $q->have_posts() ) :
    	echo '<div class="carousel">';
    
    	while( $q->have_posts() ) : $q->the_post();
    		echo '<div class="item">';
    
    			if( has_post_thumbnail() )
    				the_post_thumbnail( 'thumbnail' );
    
    		echo '</div>';
    	endwhile;
    
    	echo '</div>';
    endif;
    
    wp_reset_postdata();

    Next, you’ll need to find yourself a JS or jQuery plugin for the carousel, such as carouFredSel or jCarousel, you’ll need to match the markup in the loop above, to the markup required by the carousel plugin.

    Once you have the carousel working, you’ll need to implement some tabs, something like this is easy enough to implement.

    Please note, I haven’t tested any of the code i’ve sent you. It should work, but I may have made typos so I appolagise in advance if that is the case.

    Thread Starter YST

    (@yst)

    Hi,

    The method that you have expalined xennex81 seems effective but I like the idea of using a custom post type so the client has a menu item. Would your method work using a custom post type? My client wanted posts because then there would be physical pages for each member of the team which would help with SEO so however much I like the idea of using a custom post type I don’t think that will work unless each member under that post type will have a page?

    I understand what your code was doing but got a bit confused how to actually implement it?

    I have attached an image of the end goal. Hopefully this will make more sense. If you would be able to help me acheive this using a blog catgeory then it would be much appreciated and I would be happy to buy you a drink via paypal!

    In regards to the image below the user would click on the picture to see the bio. the arrow is only there incase they increase their team and allows the user to scroll through the pictures. also the client will only have access to edit stuff via wpadmin and so when the user adds a new team member via the post category this should update on the front end automatically.

    http://s8.postimg.org/e80q9rk51/team.png

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Display Posts in a tabbed array’ is closed to new replies.