web-dev-qa-db-fra.com

Filtrer 'the_title' avec l'option de retourner le sous-titre?

Problème:

L’application WordPress pour iPhone (et d’autres applications pour smartphone associées à WordPress) n’autorise que les champs Titre et Corps (c.-à-d. Aucun accès aux champs personnalisés).

Objectif:

Mon projet actuel nécessite que nous donnions à nos blogueurs mobiles la possibilité d'inclure un sous-titre dans leurs publications mobiles (et de bureau).

Solution:

J'aimerais utiliser un délimiteur optionnel dans le titre. Exemple:

Titre principal | Titre secondaire

Capture d'écran:

enter image description here

| est le délimiteur séparant le titre principal:

Titre principal

... du sous-titre:

Titre secondaire

Exigences du code:

Tous les codes intégrés (et plugins) qui utilisent des méthodes "title" -getting WP doivent toujours renvoyer la moitié avant le délimiteur (avec l'exemple ci-dessus) :

Titre principal

En d'autres termes, par défaut , no , les fonctions qui obtiennent un titre ne renverront jamais:

| Titre secondaire

Mon code jusqu'ici:

Le code ci-dessous est un simple point de départ.

Comme vous pouvez le constater, je filtre the_title et supprime:

| Titre secondaire

/**
 * Head/deck handling.
 *
 * Unaltered title (no quotes): "Main headline | Secondary headline"
 *
 * @see http://stackoverflow.com/a/16279114/922323
 * @see http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/post-template.php#L118
 * @see https://wordpress.stackexchange.com/questions/45589/
 */

function foo_the_title($title, $id) {

    return trim(current(explode('|', $title))); // Returns: "Main headline".

}

add_filter('the_title', 'foo_the_title', 10, 2);

En faisant ce qui précède, j'évite de m'inquiéter d'autres fonctions qui crachent le délimiteur (et les éléments qui le suivent), n'est-ce pas? Je suppose que toutes les fonctions/méthodes de "titre" seront affectées par le filtre the_title? Peut-être qu'il me manque une affaire de coin ici? UPDATE: j'ai trouvé un coin: wp_title () ... Cela me fait penser à quoi d'autre?

Des questions):

Heres où je suis coincé.

Comment puis-je écrire une fonction personnalisée (ou un filtre/autre) qui renverra la seconde moitié du titre?

Je jouais avec ça:

function foo_the_subheadline() {

    return apply_filters('the_title', '  My Custom Title (tm)  | after the stuff    ');

}

Évidemment, cela ne sert à rien (j'ai besoin de savoir manipuler la variable code/$title dans foo_the_title()).

Par exemple, ce que j'aimerais vraiment faire est quelque chose comme ceci (le pseudo-code suit, ne pas utiliser dans le monde réel ):

function foo_the_title($title, $id, $part = 'current') {

    return trim($part(explode('|', $title)));

}

add_filter('the_title', 'foo_the_title', 10, 3);

function foo_get_me_the_subheadline() {

    foo_the_title(pass the title here, pass the id?, 'end'); // Using variable function: http://php.net/manual/en/functions.variable-functions.php

}

Conclusion:

Honnêtement, j'espère que vous pourrez m'aider à trouver une conclusion. :)


MISE À JOUR (2013/05/14):

Voir ma réponse ci-dessous .

Pensées:

  • La logique fondamentale pourrait-elle être améliorée?
  • Existe-t-il des approches alternatives qui pourraient mieux fonctionner?
2
mhulse

Je ne suis pas sûr de bien comprendre votre problème, mais j’imagine que c’est votre énigme: comment arriver au titre qui n’a pas été modifié par votre filtre, si vous le filtrez partout?

Vous pouvez utiliser get_post_field() pour obtenir une copie brute de l'objet post.

Cependant, au lieu de jouer avec la sortie (et de rendre vos données sauvegardées dépendantes de la présence de filtres), je vous conseillerais de diviser un titre lors de la sauvegarde d'une post-assignation au titre comme d'habitude et de placer la seconde partie dans un champ personnalisé.

4
Rarst

Basé sur cette astuce géniale de @Rarst :

Vous pouvez utiliser la fonction get_post_field () pour en obtenir une copie brute à partir de l'objet post.

Voici une solution (possible) que je viens de cogner ensemble:

/**
 * Head/deck handling.
 *
 * Unaltered example title (no quotes): "First half | Second half"
 *
 * @see http://stackoverflow.com/a/16279114/922323
 * @see http://core.trac.wordpress.org/browser/tags/3.5.1/wp-includes/post-template.php#L118
 * @see https://wordpress.stackexchange.com/questions/45589/
 * @see https://wordpress.stackexchange.com/questions/99039/
 */

/**
 * Private helper function to return a title or deck from the title field.
 *
 * @param $title { string } The `post_title`.
 * @param $part { string } One of "current" or "end". Default: 'current'.
 * @param $delim { string } Delimiter that separates title from deck.
 * @return { string } Title before or after delimiter.
 */

function _foo_the_title_and_deck($title, $part = 'current', $delim = '|') {

    # ((if there's no delim) ? (if the deck is requested return an empty string, otherwise return the unaltered title) : return the filtered title or deck)
    return (( ! strpos($title, $delim)) ? (($part == 'end') ? '' : $title) : trim($part(explode($delim, $title))));

}

/**
 * Filter the `post_title`.
 *
 * @param $title { string } The post title.
 * @return { string } The filterd post title.
 */

function foo_the_title($title) {

    return _foo_the_title_and_deck($title);

}

# Filter `the_title`:
add_filter('the_title', 'foo_the_title', 10, 1); // Is "10" an optimal priority in this case?

# Filter `single_post_title`:
add_filter('single_post_title', 'foo_the_title', 10, 1); // IBID?

/**
 * Filter the "deck" from the `post_title`.
 *
 * @param $post_id { integer } Optional post ID. Default: FALSE.
 * @return { string } The deck from the post's title.
 */

function foo_the_deck($post_id = FALSE) {

    # Use or get the $post_id:
    $post_id = ($post_id) ? $post_id : get_the_ID();

    return _foo_the_title_and_deck(get_post_field('post_title', $post_id), 'end');

}

/**
 * Check for the existence of a deck.
 *
 * @param $post_id { integer } Optional post ID. Default: FALSE.
 * @return { boolean } TRUE if deck exists, otherwise FALSE.
 */

function foo_has_deck($post_id = FALSE) {

    if (foo_the_deck($post_id)) return TRUE;

}

Utilisation au niveau du template:

<h1><?=the_title()?></h1>

<?php if (foo_has_deck()): ?>

    <h2 class="sh4"><?=foo_the_deck()?></h2>

<?php endif; ?>

Cela semble fonctionner! Cependant, je n'ai pas encore eu le temps de faire des tests approfondis.

Idées d'amélioration:

  1. Convertir en simple OOP "doit utiliser" le plugin. Voir 2013/05/15 update ci-dessous.
  2. Incorporer add_filters qui compte pour d'autres fonctions non affectées par the_title, comme wp_title () () . Grâce au commentaire de @ DanStefancu, j'ai couvert ce cas délicat en filtrant single_post_title.
  3. Autre?

MISE À JOUR 2013/05/15

J'ai créé un plugin pour ce code et je l'ai mis ici (je suis ouvert aux commentaires). C'est mon premier WP _ plugin, (je sais qu'il pourrait être considérablement amélioré), alors soyez gentil. :)

0
mhulse