Uite o idee pentru câmpul post_object din ACF: cum ar fi să marchezi cumva postările ce au thumbnail atașat? Cum ai putea marca astfel încât să nu fie nici exagerat de vizibil? Păi… cu emoji!

(fun fact: WordPress încearcă să convertească automat emoji în imagini, prin urmare trebuie să fac embed extern la snippet…)

Și arată cam așa:

2016-08-18__49_23

Drăguț, nu? :)

Din varii motive, am ajuns să am două blog-uri: acesta și blog.iamntz.com. Și pentru că vreau ca postările de aici să apară și pe celălalt blog, folosesc plugin-ul ăsta. În principiu își face treaba binișor, doar că sunt două probleme:

  1. get_next_post și get_previous_post returnează link-uri spre celălalt blog (caz în care vizitatorul iese de pe blog) și
  2. În anumite situații, utilizatorul poate ajunge pe pagina-clonă în loc să fie redirectat spre pagina sursă.

Prima problemă o rezolvăm simplu printr-o clauză WHERE în query-ul responsabil de funcțiile folosite:

<?php
function excludeAdjacentBroadcasts($where)
{
  global $wpdb;
  $where .= " AND p.ID NOT IN( SELECT post_id from {$wpdb->base_prefix}_3wp_broadcast_broadcastdata )";
  return $where;
}

add_filter('get_previous_post_where', 'excludeAdjacentBroadcasts');
add_filter('get_next_post_where', 'excludeAdjacentBroadcasts');

A doua problemă o rezolvăm printr-un hook numit template_redirect:

add_action('template_redirect', function () {
  global $wpdb;
  $broadcasted = $wpdb->get_results($wpdb->prepare(" SELECT * from {$wpdb->base_prefix}_3wp_broadcast_broadcastdata WHERE post_id=%d", get_the_ID()));
  if (!empty($broadcasted) && is_singular()) {
    $decoded = base64_decode($broadcasted[0]->data);
    if (!empty($decoded)) {
      $decodedUnserialized = maybe_unserialize($decoded);
      if (!empty($decodedUnserialized['linked_parent'])) {
        switch_to_blog($decodedUnserialized['linked_parent']['blog_id']);
        $redirectURL = get_permalink($decodedUnserialized['linked_parent']['post_id']);
        wp_redirect($redirectURL);
        die();
      }
    }
  }
});

Ce nu sunt sigur însă este dacă este nevoie să alterez și link-ul de edit, astfel încât să editeze post-ul original…

Exclude câmpuri din ACF

Următoarea versiune de ACF introduce niște tipuri noi de câmpuri, numite Clone. Asta permite reutilizarea unui câmp sau a unui grup de câmpuri în mai multe locuri.

Doar că apar două probleme: nu mai poți adăuga condiționale și nu poți exclude doar anumite câmpuri clonate. Despre cum se rezolvă problema condiționalelor am scris aici. Mai departe îți voi arăta cum poți exclude un câmp.

1. Adăugarea setărilor în admin

Pentru că e un scenariu ceva mai generic, avem nevoie de o soluție la fel de generică. Prin urmare, adăugăm întâi o setare ce va fi vizibilă la editarea unui câmp de timpul clone:

<?php
add_action('acf/render_field_settings/type=clone', function ($field) {
  acf_render_field_wrap([
    'label' => 'Exclude Clone Fields Item',
    'instructions' => 'One field per row',
    'type' => 'textarea',
    'name' => 'exclude_clone_fields',
    'prefix' => $field['prefix'],
    'value' => isset($field['exclude_clone_fields']) ? $field['exclude_clone_fields'] : '',
    'prepend' => '',
    'append' => '',
  ], 'tr');
});

Asta ne adaugă următoarea setare în admin:

2016-08-13__04_53

2. Excluderea câmpurilor

add_filter('acf/load_field/type=clone', function ($field) {
  if (!empty($field['sub_fields']) && !empty($field['exclude_clone_fields'])) {
    $excluded = explode("\n", $field['exclude_clone_fields']);
    $excluded = array_map('trim', $excluded);

    foreach ($field['sub_fields'] as $i => $sub_field) {
      if (in_array($sub_field['name'], $excluded)) {
        unset($field['sub_fields'][$i]);
      }
    }

    $field['sub_fields'] = array_values($field['sub_fields']);
  }
  return $field;
}, 99);

3. Atât

Tot ce trebuie să faci acum este ca, atunci când editezi un câmp de tip Clonă, să adaugi în noua setare câte un nume/rând. Și cam asta e tot.