web-dev-qa-db-fra.com

Passer un attribut de shortcode à une sous-fonction

Ceci est à la fois une question WordPress et une question PHP, puisqu'un programmeur PHP peut connaître une technique que le groupe WP ne connaît pas.

J'ai essayé d'écrire un shortcode qui déclenche le code Foundation Reveal pour une utilisation en ligne avec l'éditeur WP. J'envisage de le faire fonctionner comme ceci:

[reveal size="medium" bg="true" slug="page-slug"]Open a modal with this link![/reveal]

Le shortcode spécifie la taille modale, l'utilisation ou non du fond noir et le slug de page à partir duquel incorporer le contenu dans une boucle personnalisée d'une page (ce qui nous permet d'utiliser un type de publication personnalisé non public pour stocker les données modales). . Il y a des attributs supplémentaires, mais je ne les ai pas encore écrits dans un souci de simplicité.

Voici où cela devient difficile.

Un modal se compose de deux parties, le lien et la DIV cachée. La DIV va généralement au pied de page du site. Je pourrais le mettre en ligne et résoudre mon problème, mais cela ferait des ravages dans le cache Web de Google. Non, le modal doit être un aparté dans le pied de page.

Alors je me suis un peu malin. J'avais le code court qui renvoyait le lien cible, mais je l'avais aussi fait enregistrer un crochet (placé dans footer.php) auquel un contenu DIV est attaché. Tout fonctionnait bien jusqu'à ce que je réalise un problème avec ma portée variable. Tout d'abord, voici mon code actuel:

/**
 * Foundation Reveal Shortcode
 */

// Create an action to be placed in the site footer. We will target this with the second half of the function
function foundation_reveal() {
    do_action('foundation_reveal');
}

// Set up the shortcode for the modal
function reveal_setup($atts, $content) {

    // Extract the attributes
    extract(shortcode_atts(array(
        'size'  =>  'medium',
        'slug'  =>  'dummy',
        'bg'    =>  'reveal-modal'
    ), $atts));

    $modal_link  = '<a href="#" data-reveal-id="' . $slug . '">';
    $modal_link .= $content;
    $modal_link .= '</a>';

    if ($slug == 'dummy') {
        $the_modal = '<div id="' . $slug . '" class="' . $size . ' ' . $bg . '" data-reveal>' . 'reminder/dummy content goes here' . '</div>';
    } else {
        $the_modal = '<div id="' . $slug . '" class="' . $size . ' ' . $bg . '" data-reveal>' . 'post loop based on page slug goes here' . '</div>';
    }

    function reveal_content($the_modal) {
        echo $the_modal;
    }

    add_action('foundation_reveal', 'reveal_content');

    return $modal_link;
}


/**
 * Setup shortcodes for this theme
 */

// Register all shortcodes
function gmfi_shortcodes() {
    add_shortcode('reveal', 'reveal_setup');
}

// Add shortcodes to the init hoook
add_action( 'init', 'gmfi_shortcodes');

Et comme il est utile de voir toute cette couleur codée par mon IDE, , voici un lien vers cette image .

Le problème sera évident pour tout programmeur PHP. Afin de passer quelque chose comme $ slug à la fonction secondaire, qui est accrochée au pied de page, il me faudrait passer la variable par référence.

c'est-à-dire qu'il me faudrait faire ceci:

add_action('foundation_reveal', 'reveal_content($slug)');

Malheureusement, ce n’est pas comme cela que fonctionne WordPress.

Alors, voici la question alors ... pouvez-vous penser à une autre façon de passer cette variable par référence? Parce que sinon, je devrai peut-être le sucer et écrire un script hook/action personnalisé. Cette option semble inutile s'il existe un moyen de le faire en utilisant les composants WordPress disponibles. Mais, encore une fois, s’il existait un autre moyen , l’une des suites de plugins WordPress/Foundation l’aurait probablement déjà fait.

Quoi qu'il en soit, j'ai besoin de vous tous pour m'aider à comprendre ma prochaine étape.

Merci beaucoup de rester avec moi alors que j'ai expliqué tout ça!

Remarque supplémentaire: le crochet foundation_reveal () dans le pied de page est définitivement déclenché, il ne reçoit aucune donnée de classe ou d’ID.

1
Imperative Ideas

Il y a différentes façons d'obtenir le résultat. Vous pouvez utiliser une classe, stocker le contenu de div dans une variable de classe ou d’instance et le générer en cas de besoin.

Vous pouvez également utiliser une fonction avec une variable statique pour conserver le contenu.

Je vais utiliser cette seconde alternative, la convertir en classe est un exercice pour vous;)

En complément, vous pouvez utiliser le hook 'wp_footer' pour sortir le contenu. Ainsi, vous n’aurez pas à ajouter de hook, ni à utiliser une balise template.

function reveal_setup($atts = array(), $content = '') {
  // Setup the static variable. Use an array to allow multiple calls per page
  static $the_modals = array();
  // if the function is called from wp_footer hook
  if ( current_filter() === 'wp_footer' ) {
    if ( is_array($the_modals) && ! empty($the_modals) ) {
      foreach( $the_modals as $amodal ) {
        echo $amodal;
      }
    }
  // if the function is called from shortcode
  } else {
    // Get the attributes
    $atts = shortcode_atts(
      array( 'size' => 'medium', 'slug' => 'dummy','bg' => 'reveal-modal' ),
      $atts,
      'reveal' // enable filtering
    );
    // prepare the_modal link
    $modal_link  = '<a href="#" data-reveal-id="' . $atts['slug'] . '">';
    $modal_link .= $content;
    $modal_link .= '</a>';
    // prepare the_modal content
    $modal_format = '<div id="%s" class="%s %s" data-reveal>';
    $the_modal = sprintf( $modal_format, $atts['slug'], $atts['size'], $atts['bg'] );
    if ( $atts['slug'] == 'dummy' ) {
      $the_modal .= 'reminder/dummy content goes here';
    } else {
      $the_modal .= 'post loop based on page slug goes here';
    }
    $the_modal .= '</div>';
    // save the modal content in the static modals array
    $the_modals[] = $the_modal;
    // add the present function to wp_footer hook if it is not already added
    if ( ! has_action('wp_footer', __FUNCTION__) ) {
      add_action( 'wp_footer', __FUNCTION__ );
    }
    // return the modal link
    return $modal_link;
  }
}

add_shortcode('reveal', 'reveal_setup');

C'est tout. Non testé .

PS: L’utilisation de extract est une mauvaise pratique (bien que je sache qu’elle est largement utilisée dans le code principal et dans les exemples du Codex ...)

2
gmazzap

Vous pouvez également utiliser une fonction anonyme et lui permettre d'accéder à des variables extérieures via le mot clé use (si vous avez PHP 5.3+ ).

Exemples :

add_action( 'init', function() {

    // Example 1: Append stuff to the titles    
    $stuff = '...';    
    add_filter( 'the_title', function( $title ) use ( $stuff ){
        return $title . $stuff ;
    });

    // Example 2: Display message in the footer   
    $msg = 'The End';
    add_action( 'wp_footer', function() use ( $msg ){
        echo $msg ;
    });

    // Example 3: Run an action only once  
    add_action( 'the_content', $callback = function( $content ) use ( &$callback ){
        remove_filter( current_filter(), $callback ); // __FUNCTION__ doesn't work here.
        return strtolower( $content );
    });

});
0
birgire