Jak mogę dodać opcję do listy szablonów stron z wtyczki?

10

Przez ostatnie kilka godzin szukałem sposobu na stworzenie niestandardowego szablonu strony z poziomu wtyczki, ale nie miałem jeszcze szczęścia.

To, co konkretnie próbuję zrobić, to dodać opcję do listy dostępnych szablonów stron podczas edytowania strony, a nie używając innej metody, takiej jakif( is_page( 'page-slug' ) ) { /* etc */ }

Czy istnieje zmienna globalna, którą mogę zmodyfikować, aby to zrobić?

Edytować:

Obecnie używam tego kodu, na podstawie linku @ m0r7if3r podanego w komentarzu, problem polega na tym, że uruchomi tę funkcję podczas przeglądania strony, ale nie podczas edycji strony (aby wypełnić listę rozwijaną szablonami stron) :

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;
    }

}

Edycja 2:

Wygląda na to, że ta funkcja zostanie wydana w przyszłej aktualizacji. Przeczytałem sporo biletów na ten temat i pojawiła się dyskusja, ale nie ma prawdziwej odpowiedzi (mam nadzieję na 3.4). Za chwilę wyświetli tutaj adresy URL biletów losowych.

Edycja 3:

Powyższy kod działa, ALE jedyny problem, jaki mam w tym momencie, to brak dodawania szablonu do listy rozwijanej podczas edycji / dodawania nowej strony. Próbuję kilku rzeczy i wkrótce zaktualizuję moje pytanie.

Jared
źródło
2
Czy próbowałeś coś jak to ?
mor7ifer
@ m0r7if3r (Jeśli spróbujesz, zostaw wiadomość, jak się udało - Dzięki!)
Kaiser
@kaiser Próbowałem kodu, który on polecił, jedynym brakującym linkiem jest uzyskanie meta-boxu, aby dodać szablon do listy rozwijanej (o ile mi wiadomo!).
Jared
@Jared Spójrz na to odpowiedź przeze mnie do podobnego Q i powiązanych biletów trac na dnie A. Podaj swój kod) Jeśli nie wyświetla się na każdej stronie, używasz niewłaściwych haczyków do uruchomienia instancji. Z jakich haków korzystasz?
kaiser
@kaiser Używam page_templatehaka, powyższy kod w mojej edycji jest aktualnie używany. Czy muszę użyć template_redirecthaka, a następnie dodać tam page_templatefiltr?
Jared

Odpowiedzi:

4

Filtry? Ktoś?

Nie ma tam żadnego filtra, który mógłby pomóc: page_template_dropdown($template);służy do budowania menu rozwijanego i nie można go filtrować.

Skradanie się do tablicy szablonów?

Do budowania rozwijanej zawartości wykorzystuje główny meta-box get_page_templates(). Od wewnątrz funkcja wygląda następująco:

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

Ale patrząc na get_themes();to, nie ma możliwości przechwycenia listy szablonów. Co więcej, mamy problem, że nie ma szans na uzyskanie szablonu spoza katalogu motywów…

... Udawanie motywu!

Teoria i jej wady…

Możesz użyć, register_theme_directory()aby dodać dodatkowy katalog motywów, w którym możesz umieścić szablony. Najprościej byłoby więc zarejestrować swoją wtyczkę jako folder motywów:

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

Uwaga: w tym miejscu nie jestem pewien, czy to zadziała .

Podczas aktywacji wtyczki: Następnie należy umieścić style.css.phpplik w templatesfolderze. Umożliwiłoby to dodanie zmiennych do pliku. Ta zmienna byłaby wówczas motywem nadrzędnym. Temat nadrzędny powinien być po prostu aktualnie aktywnym motywem. Następnie zaktualizuj aktywny motyw do wtyczki.

Wada # 2: Informacje o interfejsie „Wygląd”… Może dodać notatkę, że ten „Motyw” nie jest przeznaczony do użycia jako rzeczywisty Motyw. Resztę »Unikaj aktywowania tego tematu« pozostawiam twojej wyobraźni. W każdym razie: Powinno działać.

Wada nr 2: ta sztuczka z powodzeniem pozwoli uniknąć tematów potomnych. Możesz mieć jeden motyw nadrzędny. Nic więcej.

kajzer
źródło
Zgaduję więc, że nie ma rzeczywistego sposobu na użycie niestandardowych szablonów stron z nieaktywnego motywu, prawda? Mógłbym zarejestrować katalog motywów, ale szablony nie są jednak dostępne do użycia, chyba że ten motyw jest aktywny.
Jared
1
Nie całkiem. To po prostu nie powinno być, a zatem brak rdzenia. Czy próbowałeś powyższego linku do ipstenu ? Próbowałem już iść tą drogą, ale skończyłem w martwy sposób - z innym rozwiązaniem. Najlepiej byłoby śledzić bilety, naciskać i łączyć je gdziekolwiek jesteś. : /
kaiser
2

Jako sugestię dotyczącą potencjalnego obejścia problemu, czy zastanawiałeś się nad użyciem systemu plików WordPress do napisania pliku szablonu strony z wtyczki do bieżącego aktywnego katalogu motywów? W zależności od tego, ile chcesz kontrolować tego procesu, wtyczka może zapisać plik podczas aktywacji i usunąć go podczas odinstalowywania. Alternatywnie można dynamicznie tworzyć pliki szablonów stron z poziomu interfejsu użytkownika wtyczki, używając formularza do przekazywania określonych wartości, takich jak nazwa szablonu strony, która ma się pojawiać w polu rozwijanym ekranu edycji postu. Teoretycznie możesz również usunąć szablon strony z interfejsu wtyczki jednym kliknięciem i podobnie dodać wiele szablonów do różnych celów. Na blogu Otto jest dobry post na temat korzystania z systemu plików. Nie mam teraz linku do mnie, ale możesz go wyszukać.

Mam nadzieję, że wydadzą to, co zamierzaliście zrobić, zahaczając o kolejne główne wydanie.

Adam
źródło
1
Miałem wcześniej dokładnie taką metodę, ale kiedy próbowałem, miałem wiele problemów, ponieważ gdy użytkownik zmieniał motywy, nie usuwałby pliku szablonu i kopiowałby aktywny motyw i umieszczał go w innej witrynie , zaryzykowaliby przesłanie niestandardowego pliku szablonu, który nie działałby. Wiem, że istnieje kilka obejść tego problemu, ale naprawdę chcę, aby było to automatyczne . +1 za sugestię.
Jared
1
Cześć Jared. Martwiłem się również o ten sam problem. Jedynym rozwiązaniem, które mógłbym pomyśleć o dalszym rozszerzeniu tej alternatywnej metody, byłoby włączenie wtyczki po jej aktywacji do uzyskania nazwy bieżącego motywu, a jeśli użytkownik dezaktywuje / przełącza motywy, możesz usunąć plik szablonu z tego motywu i przepisać go do nowo aktywowanego motyw. Spójrz na ten link, w którym stworzył własne haki aktywacji / dezaktywacji do sprawdzania motywów. Przy odrobinie dodatkowego kodu czuję, że jest to możliwe.
Adam
Oczywiście, myślę, że to może zadziałać. Spróbuję i opublikuję wyniki w moim pytaniu. Dzięki za link, to pomaga!
Jared
1

Przeszukałem źródło i dość szokująco nie ma na to sposobu! Sugerowałem, aby włamać się do dodania drugiego pola meta z rozwijanym nadpisaniem / drugim motywem. Następnie podłącz do tego filtra:

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

zwrócić plik motywu, jeśli został zastąpiony. Oczywiście, jeśli chcesz dodać post, chcesz dodać filtr.

Jeśli chcesz być fantazyjny, możesz zeskrobać oryginalne pudełko i ponownie je utworzyć (oczywiście za pomocą filtrów, nie modyfikując kodu podstawowego).

Sugeruję również dodanie biletu trac z prośbą o tę funkcjonalność (jeśli nie ma jeszcze takiego).

Matthew Boynes
źródło
1
zgadzam się z / sugerując to dla trac.
helgatheviking
Wydaje się, że jest już w zapisie
Jared
1
Właśnie sprawdziłem to w innym pytaniu na temat szablonów pojedynczych postów . Bilety Trac można znaleźć na końcu odpowiedzi. Miejmy nadzieję na 3.4.
kaiser
1

Udało mi się to w przeszłości, usuwając domyślny metaboks szablonu strony, a następnie dodając własny metaboks. Miałem nowy metaboks z wbudowanymi get_page_templates, a następnie dodałem inne, których potrzebowałem programowo. Po zapisaniu może zaktualizować szablon strony, podobnie jak Wordpress.

gruvii
źródło
Czy miałbyś coś przeciwko pokazaniu pełnego kodu? Obecnie jest to tylko przybliżona koncepcja. Dzięki.
kaiser
1

Sprawdź zaczep theme_page_templatesużywany przez get_page_templatesfunkcję, filtr dodany od wersji 3.9 zaktualizowanej w 4.4:

apply_filters( 'theme_page_templates', $page_templates, $this, $post );
William Gu
źródło
wyjaśniono dokładniej tutaj: wordpress.stackexchange.com/a/255820/75495
cjbj
-2

Wynik wyszukiwania z DuckDuckGo, dodając szablon strony wordpress, znalazł dla mnie odpowiedź na stronie wpmu.org zatytułowanej Samouczek szablonów niestandardowych szablonów WordPress .

Zasadniczo w katalogu motywów wp-content / themes / your-theme skopiuj istniejący szablon strony do nowej wybranej nazwy pliku php. Edytuj nowy plik, zwracając uwagę na zmianę magicznej wartości właściwości „Nazwa szablonu:” w komentarzu u góry pliku.

To było wszystko. Możliwe, że jest to funkcja, która zawiera pytanie po terminie. Używam WP 3.5 z motywem twenty_eleven.

Możliwe jest również, że istnieją czystsze sposoby rozszerzenia motywu. Takie zmiany mogą zostać zastąpione aktualizacjami motywu. Mea culpa.

Douglas Lovell
źródło
Potrzebuję rozwiązania, aby dodać szablon do listy rozwijanej z wtyczki, a nie motywu. :(
Jared