Wie kann ich der Liste der Seitenvorlagen über ein Plugin eine Option hinzufügen?


10

Ich habe mich in den letzten Stunden nach einer Möglichkeit umgesehen, eine benutzerdefinierte Seitenvorlage aus einem Plugin heraus zu erstellen, hatte aber noch kein Glück.

Ich versuche speziell, der Liste der verfügbaren Seitenvorlagen beim Bearbeiten einer Seite eine Option hinzuzufügen und keine andere Methode wie die zu verwendenif( is_page( 'page-slug' ) ) { /* etc */ }

Gibt es eine globale Variable, die ich dazu ändern kann?

Bearbeiten:

Ich verwende diesen Code derzeit basierend auf dem Link @ m0r7if3r, der mir in einem Kommentar gegeben wurde. Das Problem ist, dass diese Funktion beim Anzeigen der Seite ausgeführt wird, jedoch nicht beim Bearbeiten der Seite (um die Dropdown-Liste mit den Seitenvorlagen zu füllen). ::

class JW_SiteGrader {

    private static $instance;

    private function __construct() {


        add_action( 'template_redirect', array( &$this, 'sitegrader_template_redirect' ), 20 );

    }

    public static function getInstance() {

        // Return the class data in a Singleton fashion
        if (self::$instance == null)
            self::$instance = new JW_SiteGrader();
        return self::$instance;

    }

    public function sitegrader_template_redirect() {

        add_filter( 'page_template', array( &$this, 'sitegrader_page_template' ), 10, 1 );

    }

    public function locate_plugin_template( $template_names, $load = false, $require_once = true ) {

        if ( !is_array( $template_names ) )
            return '';

        $located = '';

        $this_plugin_dir = WP_PLUGIN_DIR . '/' . str_replace( basename( __FILE__ ), '', plugin_basename( __FILE__ ) );

        foreach ( $template_names as $template_name ) {

            if ( !$template_name )
                continue;

            if ( file_exists( STYLESHEETPATH . '/' . $template_name ) ) {

                $located = STYLESHEETPATH . '/' . $template_name;
                break;

            } else if ( file_exists( TEMPLATEPATH . '/' . $template_name ) ) {

                $located = TEMPLATEPATH . '/' . $template_name;
                break;

            } else if ( file_exists( $this_plugin_dir .  $template_name ) ) {

                $located =  $this_plugin_dir . $template_name;
                break;

            }

        }

        if ( $load && '' != $located )
            load_template( $located, $require_once );

        return $located;
    }

    public function sitegrader_page_template( $template ) {

        $object = get_queried_object();

        if ( 'page' == $object->post_type ) {

            // New 
            $templates[] = "page-sitegrader.php";
            // Like in core
            $templates[] = "page-{$object->post_type}.php";
            $templates[] = "page.php";

            return locate_template( $templates );  

        }

        // return apply_filters('page_template', $template);
        return $template;
    }

}

Bearbeiten 2:

Es scheint, dass diese Funktionalität in einem zukünftigen Update veröffentlicht wird. Ich habe einige Trac-Tickets darüber gelesen und es gab einige Diskussionen, aber keine wirkliche Antwort (in der Hoffnung auf 3.4). Listet hier in Kürze Trac-Ticket-URLs auf.

Edit 3:

Der obige Code funktioniert, ABER das einzige Problem, das ich derzeit habe, ist, dass beim Bearbeiten / Hinzufügen einer neuen Seite keine Vorlage zur Dropdown-Liste hinzugefügt wird. Ich versuche ein paar Dinge und werde meine Frage bald aktualisieren.


2
Haben Sie so etwas wie versucht , diese ?
Mor7ifer

@ m0r7if3r (Wenn Sie das versuchen, hinterlassen Sie bitte eine Nachricht, wie es funktioniert hat - Danke!)
Kaiser

@kaiser Ich habe den von ihm empfohlenen Code ausprobiert. Der einzige fehlende Link besteht darin, die Meta-Box dazu zu bringen, die Vorlage zur Dropdown-Liste hinzuzufügen (soweit ich weiß!).
Jared

@Jared Schau dir diese Antwort von mir auf ein ähnliches Q und die dazugehörigen Trac-Tickets am unteren Rand des a an. Fügen Sie Ihren Code hinzu.) Wenn er nicht auf jeder Seite angezeigt wird, verwenden Sie die falschen Hooks, um die Instanz auszuführen. Welche Haken benutzt du?
Kaiser

@kaiser Ich verwende den page_templateHook. Der obige Code in meiner Bearbeitung wird derzeit verwendet. Muss ich den template_redirectHaken verwenden und dann den page_templateFilter dort hinzufügen ?
Jared

Antworten:


4

Filter? Jemand?

Es gibt dort keinen Filter, der hilft: Er page_template_dropdown($template);wird zum Erstellen des Dropdowns verwendet und ist nicht filterbar.

Sich in das Vorlagen-Array schleichen?

Zum Erstellen der Dropdown-Inhalte wird die Kern-Meta-Box verwendet get_page_templates(). Von innen sieht die Funktion wie folgt aus:

$themes = get_themes();
$theme = get_current_theme();
$templates = $themes[$theme]['Template Files'];

Aber wenn man sich das ansieht, get_themes();gibt es keine Möglichkeit, die Liste der Vorlagen abzufangen. Außerdem haben wir das Problem, dass es keine Möglichkeit gibt, eine Vorlage von außerhalb des Themenverzeichnisses zu erhalten…

... ein Thema vortäuschen!

Die Theorie und ihre Nachteile…

Sie können register_theme_directory()ein zusätzliches Themenverzeichnis hinzufügen, in dem Sie Vorlagen platzieren können. Am einfachsten wäre es also, Ihr Plugin auch als Themenordner zu registrieren:

// Register during init hook:
register_theme_directory( plugin_dir_path( __FILE__ ).'templates' );

Hinweis: Hier bin ich mir nicht sicher, ob es funktionieren wird .

Während der Plugin-Aktivierung: Dann sollten Sie eine style.css.phpDatei in Ihrem templatesOrdner ablegen. Auf diese Weise können Sie Ihrer Datei Variablen hinzufügen. Diese Variable wäre dann das übergeordnete Thema. Und das übergeordnete Thema sollte einfach das aktuell aktive Thema sein. Aktualisieren Sie dann Ihr aktives Thema auf Ihr Plugin.

Nachteil Nr. 2: Über die Benutzeroberfläche »Darstellung«… Fügen Sie möglicherweise einen Hinweis hinzu, dass dieses "Thema" nicht als eigentliches Thema verwendet werden soll. Ich überlasse den Rest von »Vermeiden Sie es, dieses Thema zu aktivieren« Ihrer Fantasie. Wie auch immer: Es sollte funktionieren.

Nachteil Nr. 2: Mit diesem Trick werden untergeordnete Themen erfolgreich vermieden. Du darfst ein übergeordnetes Thema haben. Nichts mehr.


Ich vermute also, dass es keine Möglichkeit gibt, benutzerdefinierte Seitenvorlagen aus einem inaktiven Thema zu verwenden, richtig? Ich könnte ein Themenverzeichnis registrieren, aber die Vorlagen können nur verwendet werden, wenn dieses Thema aktiv ist.
Jared

1
Nicht wirklich. Es soll einfach nicht sein und daher ein Mangel an Kern. Haben Sie den Link zu ipstenu oben ausprobiert ? Ich habe bereits versucht, diesen Weg zu gehen, endete aber auf eine tote Weise - mit einer anderen Lösung. Die beste Wette wäre, den Tickets zu folgen, sie zu pushen und zu verknüpfen, wo immer Sie sind. : /
Kaiser

2

Haben Sie als Vorschlag für eine mögliche Problemumgehung in Betracht gezogen, das WordPress-Dateisystem zu verwenden, um eine Seitenvorlagendatei von Ihrem Plugin in Ihr aktuelles aktives Themenverzeichnis zu schreiben? Abhängig davon, wie viel Kontrolle Sie über diesen Prozess haben möchten, kann Ihr Plugin die Datei bei der Aktivierung schreiben und bei der Deinstallation entfernen. Alternativ können Sie Seitenvorlagendateien dynamisch über die Benutzeroberfläche Ihres Plugins erstellen, indem Sie ein Formular verwenden, um bestimmte Werte zu übergeben, z. B. den Namen der Seitenvorlage, der im Dropdown-Feld des Post-Edit-Bildschirms angezeigt werden soll. Theoretisch können Sie die Seitenvorlage auch per Knopfdruck aus Ihrer Plugin-Benutzeroberfläche entfernen und auf ähnliche Weise mehrere Vorlagen für verschiedene Zwecke hinzufügen. Es gibt einen guten Beitrag über die Verwendung des Dateisystems in Ottos Blog. Ich habe den Link jetzt nicht bei mir, aber Sie können danach suchen.

Ich hoffe, sie veröffentlichen das, was Sie vorhatten, in der nächsten Kernversion als Hook.


1
Ich hatte eine Methode wie diese, die genau so funktionierte, hatte aber viele Probleme, als ich sie ausprobierte, denn wenn ein Benutzer die Themen wechselte, löschte er die Vorlagendatei nicht und wenn er sein aktives Thema kopieren und auf eine andere Site stellen würde Sie würden das Risiko eingehen, eine benutzerdefinierte Vorlagendatei hochzuladen, die nicht funktioniert. Ich weiß, dass es dafür mehrere Problemumgehungen gibt, aber ich möchte wirklich, dass dies automatisch erfolgt . +1 für den Vorschlag.
Jared

1
Hallo Jared, ich war auch besorgt über das gleiche Problem. Die einzige Lösung, die ich mir vorstellen könnte, um diese alternative Methode weiter zu erweitern, besteht darin, dass das Plugin bei seiner Aktivierung den Namen des aktuellen Themas erhält. Wenn ein Benutzer Themen deaktiviert / wechselt, können Sie die Vorlagendatei aus diesem Thema löschen und in das neu aktivierte Thema umschreiben Thema. Schauen Sie sich diesen Link an, über den er seine eigenen Aktivierungs- / Deaktivierungs-Hooks zum Überprüfen von Themen erstellt hat. Mit ein wenig zusätzlichem Code halte ich das für machbar.
Adam

Absolut, ich denke das könnte funktionieren. Ich werde es versuchen und die Ergebnisse in meiner Frage veröffentlichen. Danke für den Link, es hilft!
Jared

1

Ich habe die Quelle durchgesehen, und ziemlich schockierend scheint es keinen Weg zu geben, dies zu tun! Mein vorgeschlagener Hack wäre, eine zweite Meta-Box mit einer Themenüberschreibung / zweiten Themen-Dropdown-Liste hinzuzufügen. Dann haken Sie in diesen Filter ein:

# wp-includes/theme.php line 751 in 3.3.1:
return apply_filters( "{$type}_template", locate_template( $templates ) );

um Ihre Themendatei zurückzugeben, wenn sie überschrieben wurde. Natürlich möchten Sie add_filter nur hinzufügen, wenn es sich um den gewünschten Beitrag handelt.

Wenn Sie Lust haben, können Sie die Originalverpackung verschrotten und neu erstellen (natürlich über Filter, ohne den Kerncode zu ändern).

Ich würde auch vorschlagen, ein Trac-Ticket hinzuzufügen , das diese Funktionalität anfordert (falls noch keines vorhanden ist).


1
stimme zu und schlage dies für trac vor.
Helgatheviking

Es scheint bereits in der Trac zu sein: core.trac.wordpress.org/ticket/15803
Jared

1
Ich habe dies gerade für eine weitere Frage zu Vorlagen für einzelne Posts untersucht . Sie finden die Trac Tickets am Ende der Antwort. Hoffen wir auf 3.4.
Kaiser

1

Ich habe dies in der Vergangenheit erreicht, indem ich die Standard-Metabox für Seitenvorlagen entfernt und dann Ihre eigene Metabox hinzugefügt habe. Ich ließ die neue Metabox die eingebauten get_page_templates verwenden und fügte dann die anderen hinzu, die ich programmgesteuert benötigte. Beim Speichern kann die Seitenvorlage genau wie bei WordPress aktualisiert werden.


Würde es Ihnen etwas ausmachen, den vollständigen Code anzuzeigen? Derzeit ist es nur ein grobes Konzept. Vielen Dank.
Kaiser

1

Schauen Sie sich den Hook an theme_page_templates, der von der get_page_templatesFunktion verwendet wird. Der Filter wurde seit 3.9 hinzugefügt und in 4.4 aktualisiert:

apply_filters( 'theme_page_templates', $page_templates, $this, $post );

Hier ausführlicher erklärt: wordpress.stackexchange.com/a/255820/75495
cjbj

-2

Ein Suchergebnis mit DuckDuckGo zum Hinzufügen einer WordPress-Seitenvorlage ergab die Antwort für mich auf einer wpmu.org-Seite mit dem Titel WordPress Custom Page Template Tutorial .

Im Wesentlichen kopieren Sie im Themenverzeichnis wp-content / theme / your-theme eine vorhandene Seitenvorlage in einen neuen PHP-Dateinamen Ihrer Wahl. Bearbeiten Sie die neue Datei und achten Sie darauf, den magischen Eigenschaftswert "Vorlagenname:" im Kommentar oben in der Datei zu ändern.

Das war alles was dazu gehörte. Möglicherweise ist dies eine Funktion, die die Frage nachdatiert. Ich verwende WP 3.5 mit dem Thema Twenty_eleven.

Es ist auch möglich, dass es sauberere Möglichkeiten gibt, ein Thema zu erweitern. Änderungen wie diese werden möglicherweise durch Themenaktualisierungen überschrieben. Mea Culpa.


Ich benötige eine Lösung, um die Vorlage von einem Plugin zur Dropdown-Liste hinzuzufügen, nicht von einem Thema. :(
Jared
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.