web-dev-qa-db-fra.com

Comment faire un lien vers une page qui a un shortcode?

Je construis un plugin de calendrier qui peut être ajouté dans une page via un shortcode. J'essaie de trouver comment créer un lien menant à la page dans laquelle se trouve le shortcode pour le calendrier. Un autre mot si un utilisateur ajoute [calendar-shortcode] à une page que je souhaite pouvoir relier à cette page de n'importe où dans le site. Jusqu'ici, c'est ce que j'ai proposé, mais je me demande s'il existe un autre moyen.

/**
* Get page shortcode is on.
*
* @param $shortcode string. The shortcode tag
* @param $transient string. Name of transient
* @return array|mixed
*/
function get_shortcode_page($shortcode, $transient){

if(false === ($shortcode_page = get_transient($transient))){

    //Search query for shortcode tag
    $the_query = new WP_Query(array('s' => $shortcode));

    //Build simple array of page info to pass into transient
    if(isset($the_query) && $the_query->post_count != 0){
        $shortcode_page = array('ID' => $the_query->posts[0]->ID, 'permalink' => get_permalink($the_query->posts[0]->ID));

        set_transient($transient, $shortcode_page);
    }
    return null;

   }
  return $calendar_page;
}

//Use function to find shortcode page info
$page = get_shortcode_page('class-schedule', 'shortcode_calendar_page');

 /**
 * Delete shortcode transients
 *
 * If page permalink changes then delete old transients.
 *
 *
 * @param $post_id
 */
function delete_calendar_shortcode($post_id){

//get shortcode page.
$calendar_page = get_shortcode_page('class-schedule', 'shortcode_calendar_page');

    if($post_id != $calendar_page['ID'])
        return $post_id;

    $current_permalink = get_permalink( $post_id );

    if ($current_permalink != $calendar_page['permalink']){
        delete_transient( 'shortcode_calendar_page' );
   }

   return $post_id;
}

add_action('save_post',  'delete_calendar_shortcode');

Cela n'a pas été testé beaucoup mais cela fonctionne. Je veux savoir s'il existe un moyen plus efficace de le faire?

Merci

METTRE À JOUR:

Voici la version 2 ci-dessus: Ceci éliminera le besoin de la fonction get_shortcode_page () ci-dessus. Tout sera traité sur la page de sauvegarde.

/**
 * Delete shortcode transients vs 2
 *
 * If page permalink changes then delete old transients.
 *
 *
 * @param $post_id
 */
function delete_calendar_shortcode_vs2($post_id){

// If this is an autosave, our form has not been submitted,
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
    return $post_id;
}

$content_post = get_post($post_id);
$content = $content_post->post_content;

//only run if current page being saved has the shortcode
if(has_shortcode($content, 'class-schedule')){

    //Build simple array of page info to pass into transient
    $page = array('ID' => $post_id, 'permalink' => get_permalink($post_id));

    if(false !== ($calendar_page = get_transient('shortcode_calendar_page'))){

        if($page['ID'] != $calendar_page['ID'] || $page['permalink'] !=   $calendar_page['permalink']){
            delete_transient('shortcode_calendar_page');
        }
    }

    set_transient('shortcode_calendar_page', $page);
  }

return $post_id;
}

 add_action('save_post', 'delete_calendar_shortcode_vs2');

//get shortcode page from transient
$page = get_transient('shortcode_calendar_page');

Encore une fois ... Je cherche à voir s'il existe un autre moyen plus logique. J'ai également besoin d'ajouter des règles de réécriture basées sur la page sur laquelle se trouve le shortcode. J'ai figuré une étape à la fois. Merci

//////// MISE À JOUR V3 à l'aide de @true //////////////

    /**
     * Shortcode page meta builder
     *
     * Checks on save if shortcode for page exist and saves info to meta.
     *
     * @param $post_id
     */


     function has_shortcode_meta_builder($post_id){

        // If this is an autosave, our form has not been submitted,
        if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE){
            return $post_id;
        }

        $content_post = get_post($post_id);
        $content = $content_post->post_content;

        if(has_shortcode($content, 'class-schedule')){
            update_post_meta($post_id, 'has_shortcode', '1');
            delete_transient('shortcode_pages');

        }else{
            //check if meta exist in the event shortcode was removed from page.
            $meta = get_post_meta($post_id, 'has_shortcode');
            if(!empty($meta)){
                delete_post_meta($post_id, 'has_shortcode');
                delete_transient('shortcode_pages');
            }
        }

        return $post_id;
    }

    add_action('save_post', 'has_shortcode_meta_builder');

Cette fonction sera ensuite utilisée pour trouver toutes les pages avec le shortcode. Renvoyez les résultats transitoires ou lancez un appel SQL pour obtenir de nouveaux résultats afin de reconstruire le transitoire.

    /**
     * Get all posts and their permalinks that have shortcode.
     * Find pages with shortcode and store them into transient
     *
     * @global wpdb $wpdb
     * @return array. 
     */
    public function get_pages_with_shortocde(){
        global $wpdb;

        if(false === ($post_data = get_transient('shortcode_pages'))){

            $post_data = $wpdb->get_results($wpdb->prepare(
                "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s", 'has_shortcode'));

            if(!empty($post_data)){
                foreach($post_data as $row){
                    $post = get_post($row->post_id);
                    $row->slug = $post->post_name;
                    $row->post_permalink = get_permalink($row->post_id);
                }
            }
            set_transient('shortcode_pages', $post_data);
        }

        return $post_data;
    }

Enfin, ajoutez une action pour que lorsque post soient supprimés, il vérifie si la page contient ou non le shortcode. Si c'est le cas, supprimez le code court transitoire (qui sera actualisé la prochaine fois appelé)

    /**
     * Delete actions when post is deleted.
     *
     * @param $post_id
     */
     function delete_post_data($post_id){
        global $wpdb;

        //Delete shortcode transient so that it can be rebuilt excluding this page
        $content_post = get_post($post_id);
        $content = $content_post->post_content;
        if(has_shortcode($content, 'class-calendar)){
            delete_transient('shortcode_pages');
        }

    }
 add_action('before_delete_post', 'delete_post_data');
2
David Labbe

Les transitoires ne sont probablement pas la voie à suivre ici.

D'après ce que j'ai compris:

  1. Vous voulez savoir si un article a un shortcode en effectuant une recherche

  2. Vous voulez pouvoir obtenir une liste de permaliens/posts qui ont ce shortcode.

Voici ce que je suggère.

/**
 * Checks for calender shortcode and flags the post with post meta.
 * @param integer $post_id
 * @return integer
 */
function save_calender_postmeta($post_id)
{
    // Make sure this isn't an autosave.
    if(!defined('DOING_AUTOSAVE') || !DOING_AUTOSAVE){
        // Get Post Content
        $content = get_post_field('post_content', $post_id);
        // Check for shortcode
        if(has_shortcode($content, 'class-schedule')) {
            // Update (or it will insert) the 'has_calender' post meta.
            update_post_meta($post_id, 'has_calender', '1');
        }
        else {
            // Delete the has calender post meta if it exists.
            delete_post_meta($post_id, 'has_calender');
        }
    }
    return $post_id;
}
add_action('save_post', 'save_calender_postmeta');

Et puis, si vous voulez obtenir tous les articles avec calendriers, vous pouvez utiliser:

/**
 * Get all posts and their permalinks that have calenders.
 * @global wpdb $wpdb
 */
function get_calender_posts_links()
{
    global $wpdb;
    $rows = $wpdb->get_results($wpdb->prepare(
            "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s",
            'has_calender'
    ));
    if(!empty($rows)) {
        // Let's include the post permalinks with each row.
        foreach($rows as $row) {
            $row->post_permalink = get_permalink($row->post_id);
        }
    }
    return $rows;
}

Ou si vous vouliez vérifier si un seul poste avait un calendrier:

/**
 * Check if a post has a calender.
 * @param int $post_id
 * @return boolean
 */
function post_has_calender($post_id)
{
    return (get_post_meta($post_id, 'has_calender'));
}

Faites-moi savoir si c'est ce que vous cherchiez.

2
true