WordPress.org

Ready to get started?Download WordPress

Forums

[resolved] List posts by Key (34 posts)

  1. Younghusband
    Member
    Posted 8 years ago #

    I have a site that does book reviews and author interviews. I would like to use Custom Fields to keep metadata, particularly BookTitle and AuthorName, since the actual post titles are different. Then I envision having a page somewhere that outputs all posts with the BookTitle key in alphabetical order based on the Custom Field value.

    The list would end up like:

    BookTitle - PostTitle(Linked to review) - PostDate

    or for interviews

    AuthorName - PostTitle(Linked to review) - PostDate

    Being able to integrate this with ELA would be a dream, but is far beyond my skill.

    Maybe this is possible with the_meta, but it doesn't look like it.

    So far I have seen List posts based on custom values and Search Custom Fields, but I couldn't find a list by Key. Can someone point me in the right direction?

  2. geoffe
    Member
    Posted 8 years ago #

    So you'd want a get_posts function that can select only posts of a custom field and sort by them. Don't know that one exists but a plugin could be made for it. C2C has a customizable post plugin, but it doesn't do custom fields.

    Coffee2Code also has a Get custom fields plugin, but that has nothing to do with your request. If I get around to making a plugin to do this, I'll let you know.

  3. geoffe
    Member
    Posted 8 years ago #

    You know you can specify a key with the Search Custom Fields plugin you mention above?
    http://guff.szub.net/2006/04/21/search-custom-fields/

  4. Younghusband
    Member
    Posted 8 years ago #

    I wonder if I could hack that plugin to produce a "smart search" based on Key? Like every time you go to the "book index page" to see the list of books reviewed, it is actually outputting the search results for the key BookTitle.

    Using Kaf's plugin, maybe I could use link with a search string. Like:

    <a href="http://mydomain.net/?s=plugin&key=BookTitle">Index of books reviewed</a>

    This could be an interesting workaround...

    <del>Unfortunately I would like the results in alphabetical order. </del>

    Whoops!

  5. Younghusband
    Member
    Posted 8 years ago #

    The other thing is that Kaf's search doesn't output the content of the Custom Fields, just the names of the post. His results are:

    CustomFieldsKey : PostTitle
    PostDate Cat Comments

    I would like:

    CustomFieldsContent [eg. BookTitle or AuthourName] : PostTitle
    PostDate Cat

    There doesn't seem to be a function that can call the contents of a Custom Field.

  6. geoffe
    Member
    Posted 8 years ago #

    When you call the loop as usual on a search.php page, you can have posts display the content.

    I presume you are simply looking at these results to determine what can be done:
    http://guff.szub.net/?s=plugin&key=wp

    The content is formatted that way only because that is how he's formatted the loop on search.php.

    Because 's' is set in the query string, WP thinks it is a regular search, so by the Template Hierarchy, it checks for a search.php in your template folder to display the resulting posts for that search, which with the help of the plugin, also searches for posts according to the post metadata. The data written for each post is like that of any loop on your index or sidebar templates.

  7. Younghusband
    Member
    Posted 8 years ago #

    Geoffe,

    Thanks for following up on this with me.

    The content is formatted that way only because that is how he's formatted the loop on search.php.

    I understand that. I tried to set up a custom search.php page which so far looks like this:

    <?php while (have_posts()) : the_post(); ?>
    <?php query_posts('orderby=title&order=ASC'); ?>
    <div class="post">
    <a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to <?php the_title(); ?>"><?php the_title(); ?></a> - <small><?php the_time('l, F jS, Y') ?></small>
    </div>
    <?php endwhile; ?>

    But I don't want an alphabetical list of post titles, I want an alpha list of book titles which are contained in the Custom Field values. I can't figure out what to replace <?php the_title(); ?> with so it will call the Custom Field values. Maybe get_post_meta($post_id, $key, $single) without anything in post_id will return all the results.

    Any ideas?

  8. lellie
    Member
    Posted 8 years ago #

    you might need to use the get custom fields plugin to get the bit you need..

  9. geoffe
    Member
    Posted 8 years ago #

    not to worry, anything can be done. You just need to sort the results by meta_value.
    And then you can call the meta in the loop with the_meta, or get_post_meta as you suggest but to sort you'll need to add this filter into the plugin:

    add_filter('posts_orderby', 'meta_value');

    I think you should add it in the line above the
    return $where;
    line inside the szub_search_custom_where() function in the plugin.

  10. Younghusband
    Member
    Posted 8 years ago #

    The custom fields plugin seems to (almost) be able to handle this, in a much more elegant way than the "smart search" approach. I can now produce a list of BookTitles on a custom-archive.php page with the following code:


    <?php query_posts('orderby=title&order=asc&showposts=-1'); ?>
    <?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
    <?php echo c2c_get_custom('BookTitle', '<li>', '</li>', '', '', '' ); ?>
    <?php endwhile; ?>
    <?php endif; ?>

    So far this is great, but now the problem is creating links to the actual reviews of the books.

    I would like to stick the following in there somewhere:


    <a href="<?php the_permalink() ?>" style="text-decoration:none;" rel="bookmark" title="Permanent Link: <?php the_title(); ?>">
    <?php the_title(); ?>
    </a>

    ... but unfortunately it seems when c2c_get_custom grabs the field values, it doesn't have any info on the actual post the field values are associated with. Unless this has something to do with the Loop, or with the query.

  11. geoffe
    Member
    Posted 8 years ago #

    But what you are doing is looping through posts while calling only the BookTitle meta information, if I understand correctly.

    If you put the_permalink() into the loop, it should produce the permalink for each post including the ones that don't have BookTitle meta information. There isn't anything in your loop or restrictions to keep the posts to only posts that have BookTitle meta info.

    And doesn't ordering by title just order by the title of the post? If you put the add_filter('posts_orderby', 'meta_value'); line into the search plugin, it will set the order of posts by meta_value, which will be the Book titles if the meta_key is BookTitle. Or did you try that and it didn't work?

  12. Younghusband
    Member
    Posted 8 years ago #

    If you put the_permalink() into the loop, it should produce the permalink for each post including the ones that don't have BookTitle meta information.

    That is exactly what happened, disappointingly.

    If you put the add_filter('posts_orderby', 'meta_value'); line into the search plugin, it will set the order of posts by meta_value, which will be the Book titles if the meta_key is BookTitle. Or did you try that and it didn't work?

    It returned an error when I tried to put it in.

  13. Younghusband
    Member
    Posted 8 years ago #

    Actually, I am lucky since I have a specific "Reviews" (cat=2) and "Interviews" (cat=4) categories, so I can limit the query to these cats specifically and use the_permalink. The last thing now is ordering. I tried to use meta_value and the_meta to no avail.

    Here is what I have done so far:

    <?php query_posts('orderby=meta_value&order=desc&showposts=-1&cat=2'); ?>
    <?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
    <a href="<?php the_permalink() ?>" style="text-decoration:none;" rel="bookmark" title="Permanent Link: <?php the_title(); ?>"><?php echo c2c_get_custom('BookTitle', '', '', '', '', '' ); ?></a>

    <?php endwhile; ?>
    <?php endif; ?>

  14. geoffe
    Member
    Posted 8 years ago #

    Just realized why my solution in ordering by meta_value can't be done -- because it's not in the selected values of the SQL query. [Which is also why it won't work for your ordering in the loop.]

    You'll need to make a unique query for posts in order to get your posts sorted by meta_value. The default is to select all fields from the posts table but you'll need a join and select from postmeta table.

  15. geoffe
    Member
    Posted 8 years ago #

    Here we go. Try using this:
    <?php
    if ( $recentposts =
    $wpdb->get_results("SELECT ID, post_title, post_date, post_content, meta_value, guid FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id WHERE post_status = 'publish' ORDER BY meta_value DESC LIMIT 5")) {
    foreach ($recentposts as $post) {
    echo "{$post->meta_value} - < a href=\"{$post->guid}\">{$post->post_title} - {$post->post_date}
    ";
    } } ?>

  16. Younghusband
    Member
    Posted 8 years ago #

    Thanks for that Geoffe. Is there something I have to fill in here? It seems to capture the wrong metadata. Since I have wp_texturize installed, the output is a big unending block like this:

    wptexturize - < a href="permalink">PostTitle - TimeDate

    Where should I put in BookTitle in that code snippet of yours?

  17. geoffe
    Member
    Posted 8 years ago #

    oops, I had removed that between testing it myself.

    You want the query to read:
    SELECT ID, post_title, post_date, post_content, meta_value, guid FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id WHERE post_status = 'publish' AND meta_key='BookTitle' ORDER BY meta_value, post_date DESC LIMIT 5

    it's in the WHERE statement. I also added in post_date in the ORDER BY statement

    2 questions:
    Which version of WP are you using? Are you putting the snippet into a post (even a Page post) or into a template (such as index.php)?

    EDIT: you also need to add in a < /a > tag after {$post->post_date} -- the formatting here removed that on me.

  18. Younghusband
    Member
    Posted 8 years ago #

    Geoffe,

    She be workin' perfect matey!

    Here is the code I am using (in case anyone else is trying to do the same thing):

    <?php
    if ( $recentposts =
    $wpdb->get_results("SELECT ID, post_title, post_date, post_content, meta_value, guid FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id WHERE post_status = 'publish' AND meta_key='BookTitle' ORDER BY meta_value, post_date DESC LIMIT 5")) {
    foreach ($recentposts as $post) {
    echo "<a href="{$post->guid}" title="Permanent Link: {$post->post_title}">{$post->meta_value}</a>
    ";
    } } ?>

    Comes out brilliant for both BookTitles and AuthourNames. Thanks so much for your help.

    And for the record, I am using WP 2.0.2 and I have the snippet in a special template called indexes.php which will contain both books and interviews in two long lists.

    Thanks again!

  19. geoffe
    Member
    Posted 8 years ago #

    excellent. congratulations.

  20. Dgold
    Member
    Posted 8 years ago #

    Wowzers, what a thread. I'm gonna try to figure out that sollution, b/c this is more like what I was trying to accomplish when I asked Kaf for the Custom Fields Search.

    In my case, Posts are Songs, which have custom fields: Singer, Songwriter, Album...

    and I would like to make a Page that lists, for example:

    All songs by Singer(KEY): Susan Smith(VALUE)
    --Songtitle (post title) 1 which is sung by Susan
    --Songtitle (post title) 2 which is sung by Susan
    --Songtitle (post title) 3 which is sung by Susan

    All songs on Album(KEY): Best Of Susan
    --Songtitle (post title) 1 which is on Best Of
    --Songtitle (post title) 1 which is on Best Of
    --Songtitle (post title) 1 which is on Best Of

    @Younghus, do you think your solution would fit my scenario? It seems similar?

  21. geoffe
    Member
    Posted 8 years ago #

    It should fit, although you will want to remove the LIMIT 5 if you want to get all songs.

    And you'll need to specify WHERE post_status = 'publish' AND meta_key='Singer' AND meta_value='Susan Smith'

    just to get all the songs by Susan Smith.

  22. Dgold
    Member
    Posted 8 years ago #

    Cool, thanks for your work on this. I am going to try it this weekend.

  23. davidchait
    Member
    Posted 8 years ago #

    Obviously, you could also pretty easily connect up with something like CG-Amazon to give you live links direct to a single book, or a list of books by an author, prices or not, etc. Just a thought -- happened upon this discussion and thought I'd throw in $0.02. ;)

    -d

  24. kalico
    Member
    Posted 8 years ago #

    Ok, I'm trying to figure out how this applies to what I'm trying to do, and right now I'm lost! I hope someone can help me sort through it.

    I have one custom field on which I want to sort: author.

    I want a list of post titles, sorted by the "author" field, and I want to display the post title, and the author's name.

    At present, I have them sorted by the post title, which is the name of the book. See http://www.timelessword.com/wordpress

    I just want to sort by author (the meta_key), not post title. I've read http://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query but I'm lost....it says you have to have a meta_key of "tag" and a meta_value of "email" -- I realize I could change those for my needs, but it doesn't seem to accomplish a sorting function.

    Any help would be most appreciated. I can tell from posts that this is something lots of people want to do, so I'm surprised that there isnt' a simpler way to accomplish it.

    Thanks in advance for any help you can provide!

  25. geoffe
    Member
    Posted 8 years ago #

    Looks like you want to do much the same thing as Younghusband and Dgold above.

    Try:
    <?php
    if ( $recentposts =
    $wpdb->get_results("SELECT ID, post_title, post_date, meta_value, guid FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id WHERE post_status = 'publish' AND meta_key='author' ORDER BY meta_value, post_title DESC")) {
    foreach ($recentposts as $post) {
    echo "< a href="/wordpress/?p={$post->ID}" title="{$post->post_title}">{$post->post_title}< /a> by {$post->meta_value}
    <hr>
    ";
    } } ?>

    ...to get a list of every Book sorted by author name (1st) and secondarily sorted by title.

    If you had permalinks set up, you could use this in the foreach loop:
    <?php
    foreach ($recentposts as $post) {
    echo "< a href="{$post->guid}" title="Permanent Link: {$post->post_title}">{$post->post_title}< /a> by {$post->meta_value}
    ";
    } ?>
    ...but you haven't set permalinks, which is okay.

    If you were to set a value for meta_value, it would be an author's name if the key was 'author'. When you want to list every book/post, of every author, you wouldn't want to set meta_value.

  26. kalico
    Member
    Posted 8 years ago #

    Thanks Geoff. Where exactly in my file do I put this? Inside the loop? What do I remove? Here is my present code:

    <?php
    $posts = query_posts($query_string . 'cat=2&orderby=title&order=asc&posts_per_page=-1');
    if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <div class="post" id="post-<?php the_ID(); ?>">
    <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> by <?php foreach(get_post_custom_values('author') as $author) {
    echo $author;
    } ?>
    </div>
    <?php endwhile; else: ?>
    Sorry, no posts matched your criteria.
    <?php endif; ?>

    No idea if it's "good" code or not, but it works. When I try to add the new hunk of code, I get error messages. I'm sure I'm putting it in the wrong place.

    Also, I do intend to use permalinks ultimately, I just haven't set them up yet. Trying to get the bugs worked out before I add that, because it always causes grief with my server. But the code when using permalinks is certainly simpler. Maybe I should get that in place first.

    Thanks again for your help. :)

  27. geoffe
    Member
    Posted 8 years ago #

    The code I offered is a replacement for the Loop script that you have pasted there.

  28. kalico
    Member
    Posted 8 years ago #

    When I do that, I get:

    Parse error: parse error, unexpected '?' in /var/www/public_html/kalico2/virtualhosts/timelessword/wordpress/wp-content/themes/tw/index.php on line 11

    Line 11 is the "echo" line.

    I appreciate your help with this. I'm stymied. :)

  29. geoffe
    Member
    Posted 8 years ago #

    oops, you need to escape (by \ - backslash) the quotes in the code for the echo statement. I'd copied what Younghusband had written for his modification but you'll need to escape the quotes in the echo statement because that was an oversight and obvious error.

    So:

    <?php
    if ( $recentposts =
    $wpdb->get_results("SELECT ID, post_title, post_date, meta_value, guid FROM $wpdb->posts LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id WHERE post_status = 'publish' AND meta_key='author' ORDER BY meta_value, post_title DESC")) {
    foreach ($recentposts as $post) {
    echo "< a href=\"/wordpress/?p={$post->ID}\" title=\"{$post->post_title}\">{$post->post_title}< /a> by {$post->meta_value}
    <hr>
    ";
    } } ?>

    is what you want. And I've discovered why this probably occurred: If I put in a backslash \ here, when I go back and edit the post, silly WordPress Support forums will remove all \'s in my post.

  30. geoffe
    Member
    Posted 8 years ago #

    Let that be a WARNING to anyone copying some of the code above or ever attempting to use backslashes in support forums. The echo statements above that contain quote marks - " - between their quote marks need to have those inner quote marks escaped with a backslash - \.

    And these forums don't remove all \'s, only the ones that precede a ". So if I type \", and go back and edit this post, it will become ". Word to the wise.

Topic Closed

This topic has been closed to new replies.

About this Topic