Viewing 5 reply threads
  • Author
    Posts
    • #8910
      Sara
      Participant

      Hello the community,

      I have 2 CPT, event and city.
      I added a select box in event, so the admin could link the events with the appropriate cities. Until now all seems fine.

      piklist('field', array(
        'type' => 'select',
        'field' => 'city_event', // had to add it to save data (not in the doc)
        'title' => 'Accociated City',
        'choices' => piklist(get_posts(array(
          'numberposts' => -1,
          'post_type' => 'city',
        )),
        array('ID', 'post_title')),
        'relate' => array( 'scope' => 'post' ),
        'attributes' => array( 'class' => 'multiple' )
      ));

      But could you please explain the 3 last lines.
      Does the select retrieve only the ID and the post_title?
      Should I set attribues when I only need a simple choice?
      Should I set the scope to post or meta_post?

      In the DB I get ma data listed this way:

      meta_id : an integer
      post_id : the event id
      meta_key : city_event
      meta_value : city id

      But I couldn’t get the right result displayed for the front-end.
      I’m sorry if this is messy, I tried so many things I ended up dizzy.

      $related_events = get_posts(array(
          'post_type' => 'event',
          'numberposts' => -1,
          'post_belongs' => $post->ID,
             'suppress_filters' => false,
             'relate_query' => array(
                array(
                  'id' => $post->ID,
                  'relate' => 'belongs'
                 ))
           ));

      print_r($related_events) gives me the 4 event posts, but I in the WP_Post Object I don’t see anything to relate my events to the cities.
      Should I use compare? Should I wrap things up into an if statement, if so, what do I check the condition with?

      Could you please help me with this?
      Thank you for reading πŸ™‚

    • #8928
      Jason
      Keymaster

      Hi @Sara!

      Happy to help you with this. πŸ™‚

      First, did you happen to see this in the documentation? https://piklist.github.io/docs/tutorials/relationships/working-with-field-relationships/

      Let’s break down your first query:
      'field' => 'city_event',
      You shouldn’t need this. If you do need it for some reason then the relate field isn’t working.

        'choices' => piklist(get_posts(array(
          'numberposts' => -1,
          'post_type' => 'city',
        )),
        array('ID', 'post_title')),

      What’s happening there is that get_posts() is retrieving an array of WP_Post objects that contains all of your city posts. From there, the piklist() function is “plucking” the array, meaning that it’s creating a new array from the WP_Post array wherein the new array key is the ID and the value is the post_title. For a relate field to work it needs the value stored (key) to be the object ID, and the post_title is so the user knows what they’re looking at when selecting an option.

      
      'relate' => array( 'scope' => 'post' ),

      This is the “magic” line that sets the field up as a relate field. The scope here would either be ‘post’, ‘user’, or ‘comment’, based on what you’re connecting to. Since you’re connecting two posts, the scope would be ‘post’. If you see 'scope' in the context of the root field parameters, that’s for non-relate fields and most times doesn’t need to be worried about.

      Here’s a working example of how I would structure what you’re doing:

      piklist('field', array(
        'type'      => 'select',
        'label'     => 'Accociated City'
        'choices'   => piklist(get_posts(array(
          'post_type'   => 'city',
          'numberposts' => -1
        )), array('ID', 'post_title')),
        'relate'    => array(
          'scope'     => 'post'
        ),
        'attributes'=> array(
          'multiple'  => 'multiple',
        )
      ));

      $related_events = get_posts(array(
          'post_type' => 'event',
          'numberposts' => -1,
          'post_belongs' => $post->ID,
             'suppress_filters' => false,
             'relate_query' => array(
                array(
                  'id' => $post->ID,
                  'relate' => 'belongs'
                 ))
           ));

      For this, you did get just a bit mixed up. Here’s what it should be structured like:

      $related_events = get_posts(array(
        'post_type'        => 'event',
        'numberposts'      => -1
        'suppress_filters' => false,
        'relate_query'     => array(
          array(
            'id'    => $post->ID,
            'relate'=> 'has'
          )
        )
      ));

      First, I put 'suppress_filters' in the root level parameters where it belongs.

      Next, I changed 'relate' to 'has'. The reason is that since the city selection is on the event page, the event has the cities, not the other way around. And since we’re querying an event, we’re saying we want to limit the events by which cities the queried event has.

      Hope this helps! I think the example in the docs should help, too!

    • #8936
      Sara
      Participant

      Hi Jason πŸ™‚

      Thank you very much for taking the time to explain me. It helped understand better how it all works, which makes sense actually (about choices, IDs and titles).
      The scope explanation was indeed enlightening.

      So, yes I began working on this with the tutorial relationship example, but as it didn’t work, I suspected I didn’t understand (no surprise).

      'field' => 'city_event'
      I added this because after selection, the data didn’t seem to be stored. I applied the changes you adviced, but again, once I select a city, the select box returns to the 1st value in the list 😐

      attributes' => array('multiple' => 'multiple',)
      I removed the ‘multiple’ attribute because I didn’t want multiple city choices, only one – correct?

      Now my print_r($related_events) still display my 4 events.
      I tried to foreach, var_dumped all I thought about. Still doesn’t work.
      It always retrives my 4 events unsorted.

      I also tried moving my CPTs out of my mu-pluings folder in functions.php file, but it didn’t help either.
      I ended up pasting your entire code to be sure, still not working.

      I really wonder what I am missing here…

    • #8939
      Jason
      Keymaster

      Glad that was helpful! πŸ™‚

      Let’s talk about how relate data is stored for a moment. In your case you have an event post type relating to a city post type. As mentioned, in this case the event owns the city; that is to say, when creating an event the user selects which city it will be in β€” makes sense!

      The way Piklist stores this is that in the city’s meta it adds a __relate_post meta key wherein the value is the ID of the event that owns it. This is later used when performing relate queries.

      So if you look at the event’s meta, you won’t see anything added about the city. Why? Because it’s not designed to put anything there. Look at the city’s meta. You should find it there. For this reason, you don’t need to specify a field, as relate fields are a special type which store in their own way.

      And, yes, if you only want one then remove the multiple line.

      To debug this, first check the city’s meta to see if the relate data is being stored.

      Next, double-check your query. Is $post a WP_Post object as you’re expecting? Is the ID what you’re expecting? Make sure you have 'suppress_filters' => false, otherwise WordPress will restrict WordPress from adjusting the query for the relate parameters (annoying that true is the WP default for that function, but is false for WP_Query queries).

      If that doesn’t work, zip up the related files and shoot them over to [email protected] so we can take a closer look. I’m quite sure it’s something simple, though, and if you can figure it out you’ll be the better for it!

      Quick tip:
      Since you’re doing a simple query, you can do a shorthand relate format like this:

      $related_events = get_posts(array(
        'post_type'        => 'event',
        'numberposts'      => -1
        'suppress_filters' => false,
        'post_has'         => $post->ID
      ));

      Much easier to read and is great for simple queries. πŸ™‚

    • #8951
      Jason
      Keymaster

      Wanted to throw in here that I took this opportunity to improve the Relationship documentation, per our discussion: https://piklist.github.io/docs/tutorials/relationships/working-with-field-relationships/

    • #8985
      Sara
      Participant

      Thanks Jason,

      Sorry for the late reply, got to dive into something else for a while.
      Gonna try to solve this out with a fresh mind πŸ™‚
      Yes, I also think it must certainly be something simple.

      Thank you for your patience, and improving the documentaion πŸ™‚

      EDIT
      Did a fresh install and all went great!
      I’m really going to LOVE Piklist! πŸ™‚

Viewing 5 reply threads
  • You must be logged in to reply to this topic.