Hi all,
I’m using the relationship field from Advanced Custom Fields to create a ‘collection’ of posts which I then display in a list view in my theme, I’d like to add the ability for visitors / users to up/downvote posts within the collection (reddit / producthunt style) and for the list to reorder accordingly, is this possible?
It’s also worth mentioning that a post can be contained in multiple collections, so votes would have to be at the level of the collection, rather than assigned to the post.
Finally when a user upvotes an item in a collection it should also register a global 'like' against the post.
I already have a theme setup with the layout / design, just looking for help getting the functionality here, any help would be massively appreciated!
Happy to provide more details if they're needed.
DW
Andrea P answers:
Hello Dale!
at the moment I can't think of an easy way to achieve what you want by using the relational field..
My suggestion is to use a repeater field to list the collection of posts, and when you add a post to the collection, you'll have to look at the posts in your post listing in wp admin, and put its ID into the repeater row.
in my example I've then used the ID only to create a link to the post, but you could use it basically for grabbing anything else that you could do within a posts relationships field loop.
(the only thing that you cannot do is setup_postdata($row['id']), because we will need to get the current page id while into the repeater loop, and if you setup the post data to loop the posts, the update_postmeta() will update the looped post field rather than the page in which the collections is being displayed)
for the following code, I've created a repeater like this:
repeater name: posts_repeater
ROW:
id
points
post_name
you can use your own names and change the following code accordingly
place this code in the template of the page where you want to display the list
<?php
// get the repeater rows
$posts_repeater = get_field('posts_repeater');
// set up an array for ordering
$ordering_list = array();
// populate ordering list
foreach( $posts_repeater as $i => $row ) {
$ordering_list[ $i ] = $row['points'];
// setup an additional value within the repeaters rows with the field name to be used later (this is the structure used for naming the repeater subfields in database: $ParentName_$RowNumber_$ChildName
$posts_repeater[$i]['data_name'] = 'posts_repeater_'.$i.'_points';
}
// multisort the posts array based on the ordering list
array_multisort( $ordering_list, SORT_DESC, $posts_repeater );
// loop through repeater
if( $posts_repeater ): ?>
<ul>
<?php foreach( $posts_repeater as $i => $row ): ?>
<?php
// if this post has been just downvoted
if ( $_GET['downvote'] && $_GET['downvote']==$row['id'] ) {
// update the points
$row['points'] = $row['points'] - 1;
update_post_meta(get_the_ID(), $row['data_name'], $row['points']);
//update_field($row['data_name'], $row['points']) ;
}
// if this post has been just upvoted
if ( $_GET['upvote'] && $_GET['upvote']==$row['id'] ) {
// update the points
$row['points'] = $row['points'] + 1;
update_post_meta(get_the_ID(), $row['data_name'], $row['points']);
//update_field($row['data_name'], $row['points']) ;
}
?>
<li><?php echo $i+1; ?>. <a href="<?php get_permalink($row['id']); ?>" target="_blank"><?php echo $row['post_name']; ?></a> - points: <?php echo $row['points']; ?> <span class="vote-link"><a href="?upvote=<?php echo $row['id']; ?>">Like</a> | <a href="?downvote=<?php echo $row['id']; ?>">Dislike</a></span></li>
<?php endforeach; ?>
</ul>
<?php endif; ?>
the above code will set different points for each page where you will create the collections rows. basically it will update the value of the meta field "points" of the specific row within this post/page
let me know if it wasn't what you were looking for.
cheers!
Andrea
Dale Williams comments:
Hey Andrea,
Thanks for the reply... the solution you provided is really great but not ideal for the website I'm working on. I've PMed you some additional details... please take a look if you get a chance!
Thanks
Andrea P comments:
ok Dale
I've replied and waiting for more details. I'm not sure in which aspect the solution doesn't suit your requirements, but another solution might be to create an option page where you can setup the collections, and then use a custom field to select which collection you want to attach to a post. in this way you could append the very same collection to 2 different posts, but when voting, the vote will be recorded for the collection itself, no matter from which post has been voted.
if you send me more details, I can write down some code for you for an extra fee. (it would be nice if in the meanwhile you'd assign this question prize to me)
cheers!