Includerea unui fișier PHP în Conținut folosind [shortcode]
Iată ce am la dispoziție
Nu reușesc să găsesc o modalitate simplă de a include un fișier în editorul de conținut folosind un shortcode.
De exemplu, dacă aș dori să includ form.php în Pagina mea de Contact, cum aș putea face acest lucru folosind un shortcode?
Mai jos este ceea ce am încercat să implementez, fără succes.
Orice ajutor ar fi apreciat!
// Implementarea Shortcode-ului
function magic_stuff($atts) {
// activăm output buffering pentru a captura ieșirea scriptului
ob_start();
// includem fișierul (conținutul va fi salvat în buffer-ul de ieșire)
include(TEMPLATEPATH.'/wp-content/themes/grainandmortar/inc_static/test.php');
// salvăm și returnăm conținutul care a fost generat
$content = ob_get_clean();
return $content;
}
//înregistrăm handler-ul pentru Shortcode
add_shortcode('magic', 'magic_stuff');
Iată o altă metodă de a face acest lucru, utilizând get_template_part
din WordPress
function include_file($atts) {
$a = shortcode_atts( array(
'slug' => 'NULL',
), $atts );
if($a['slug'] != 'NULL'){
ob_start();
get_template_part($a['slug']);
return ob_get_clean();
}
}
add_shortcode('include', 'include_file');
exemple:
[include slug="form"]
[include slug="sub-folder/filename_without_extension"]

Am modificat niște cod dintr-un articol vechi de blog pentru a face asta și pentru a permite atașarea de query-strings la fișier.
Creditul original merge către amberpanther.com, și se pare că au făcut și un plug-in din asta.
//crearea shortcode-ului [include] care acceptă o cale de fișier și un șir de interogare
//această funcție a fost modificată dintr-un post pe www.amberpanther.com pe care îl puteți găsi la linkul de mai jos:
//http://www.amberpanther.com/knowledge-base/using-the-wordpress-shortcode-api-to-include-an-external-file-in-the-post-content/
//ÎNCEPUT cod amberpanther.com
function include_file($atts) {
//dacă a fost specificată calea fișierului
extract(
shortcode_atts(
array(
'filepath' => 'NULL'
), $atts
)
);
//ÎNCEPUT parte modificată a codului pentru a accepta șiruri de interogare
//verifică dacă există un șir de interogare după calea fișierului
if(strpos($filepath,"?")) {
$query_string_pos = strpos($filepath,"?");
//crează o variabilă globală pentru șirul de interogare pentru a putea fi accesat în fișierele incluse dacă este necesar
//de asemenea, extrage-l din numele curat al fișierului pe care îl vom stoca într-o variabilă nouă pentru includere
global $query_string;
$query_string = substr($filepath,$query_string_pos + 1);
$clean_file_path = substr($filepath,0,$query_string_pos);
//dacă nu există un șir de interogare
} else {
$clean_file_path = $filepath;
}
//SFÂRȘIT parte modificată a codului
//verifică dacă a fost specificată calea fișierului și dacă fișierul există
if ($filepath != 'NULL' && file_exists(get_stylesheet_directory_uri() . "/" . $clean_file_path)){
//activează bufferizarea output-ului pentru a captura rezultatul scriptului
ob_start();
//include fișierul specificat
include(TEMPLATEPATH.$clean_file_path);
//atribuie output-ul fișierului variabilei $content și curăță buffer-ul
$content = ob_get_clean();
//returnează $content
//returnează este important pentru ca output-ul să apară în poziția corectă
//în conținut
return $content;
}
}
//înregistrează handler-ul Shortcode
add_shortcode('include', 'include_file');
//SFÂRȘIT cod amberpanther.com
//shortcode cu șir de interogare exemplu:
//[include filepath="/get-posts.php?format=grid&taxonomy=testing&term=stuff&posttype=work"]
L-am setat să extragă din stylesheet uri (pentru a funcționa cu teme copil și altele asemenea), dar puteți ajusta cu ușurință acel cod pentru a extrage de oriunde (inclusiv din directoarele de plug-in-uri), sau puteți să-l eliminați cu totul și să folosiți calea completă atunci când includeți fișierul. Puteți chiar să adăugați o condițională cu un caracter de declanșare la început care să-i spună să folosească o cale specifică în funcție de primul caracter al numelui fișierului, cum ar fi folosirea unui "#" pentru directorul șablon, etc.
Îl folosesc pentru a include un fișier numit get-posts.php care se află în directorul meu de șablon și formatează output-ul diverselor postări pe baza unei serii de parametri furnizați în șirul de interogare. Mă scapă de nevoia de șabloane speciale pentru că pot include fișierul, să-i trimit un format și va afișa postările cu markup-ul pe care l-am specificat în fișierul get-posts.php.
De asemenea, permite clienților să includă tipuri personalizate de postări în postări de blog reale în formate specifice și este destul de util.
Spuneți-mi dacă aveți nevoie de clarificări la ceva.

Nu ar trebui să folosești TEMPLATEPATH
sau STYLESHEETPATH
. Folosește în schimb get_template/stylesheet_dir()
sau echivalentul *_url()
pentru căi/URI-uri

ericissocial Mulțumesc mult! O să conectez tot și o să încerc, o să-ți spun cum merge.

Nicio problemă, ar trebui să urmezi recomandarea lui kaiser și să folosești funcționalitatea GET_template în loc de TEMPLATEPATH pe care o aveam în cod. Kaiser, mulțumesc pentru atenționare, o să editez codul din răspunsul meu când nu-l văd pe telefon.

Există o eroare în soluția furnizată de @adedoy, deoarece $slug nu este definit niciodată. Această soluție a funcționat pentru mine:
function include_file($atts) {
$atts = shortcode_atts(
array(
'path' => 'NULL',
), $atts, 'include' );
ob_start();
get_template_part($atts['path']);
return ob_get_clean();
}
add_shortcode('include', 'include_file');
Utilizare: [include path="calea/din/rădăcină"]

Bine, în primul rând aș renunța la buffering-ul de ieșire.
A doua modificare:
include(TEMPLATEPATH.'/wp-content/themes/grainandmortar/inc_static/test.php');
În:
include( get_stylesheet_directory() . '/inc_static/test.php');
În final,
Citind documentația aici: https://codex.wordpress.org/Shortcode_API
Trebuie să returnați ceva, dacă test.php nu afișează ceva într-un mod returnabil, veți avea probleme.
Așadar, asigurați-vă că test.php face ceva de genul:
$output = "CONȚINUT"; // o variabilă pe care o puteți returna după include.
// sau
function test() {
// executați acțiuni
return $rezultat; // o funcție care returnează o valoare pe care o puteți apela după include.
}
Apoi, după ce includeți fișierul test.php -- pur și simplu returnați $output
sau faceți ceva de genul return test();
.

Doar sunt curios despre raționamentul tău - de ce să nu folosești bufferizarea ieșirii pentru shortcode-uri?

Salut @mattLummus -- la finalul zilei, este o chestiune de perspectivă. Cred că nu ai NEVOIE de ea pentru a atinge scopul și nu câștigi prea mult făcând asta -- în plus, voi repeta ceea ce s-a spus aici: https://stackoverflow.com/questions/5454345/output-buffer-vulnerabilities-php -- "Bufferizarea ieșirii este considerată urâtă dacă este folosită pentru a ocoli avertismentul vechi 'Cannot send headers, output already started at...'. Bufferizarea ieșirii este folosită atunci pentru a compensa o proastă proiectare..."

Da, într-adevăr pare o soluție cam "hacky" în acel caz particular. În general, când folosim Output Buffers, nu este pentru a rezolva o altă problemă, ci pur și simplu pentru că suntem într-un caz în care scriem mai mult markup decât PHP și preferăm sintaxa OB (putând să ieșim din PHP și să scriem HTML simplu în loc de o grămadă de declarații echo și HTML scris în șiruri de caractere).
Mulțumesc pentru răspuns, în orice caz!

Am descoperit că codul de includere scris inițial de cei de la AmberPanther nu a funcționat prea bine pentru mine, așa că am găsit un alt plugin WordPress care face practic același lucru. Se numește Include Me, dezvoltat de Stefano Lissa. Utilizarea este destul de simplă: scrii calea către fișier, începând din directorul rădăcină al site-ului tău.
De exemplu, într-o pagină WordPress ai putea scrie:
[includeme file="wp-content/themes/your-theme/code/example-code.php"]
iar în fișierul functions.php ai include:
<?php
if (is_admin()) {
include dirname(__FILE__) . '/admin.php';
} else {
function includeme_call($attrs, $content = null) {
if (isset($attrs['file'])) {
$file = strip_tags($attrs['file']);
if ($file[0] != '/')
$file = ABSPATH . $file;
ob_start();
include($file);
$buffer = ob_get_clean();
$options = get_option('includeme', array());
if (isset($options['shortcode'])) {
$buffer = do_shortcode($buffer);
}
} else {
$tmp = '';
foreach ($attrs as $key => $value) {
if ($key == 'src') {
$value = strip_tags($value);
}
$value = str_replace('&', '&', $value);
if ($key == 'src') {
$value = strip_tags($value);
}
$tmp .= ' ' . $key . '="' . $value . '"';
}
$buffer = '<iframe' . $tmp . '></iframe>';
}
return $buffer;
}
// Aici pentru că funcția TREBUIE definită înainte de "add_shortcode" deoarece
// "add_shortcode" verifică numele funcției cu "is_callable".
add_shortcode('includeme', 'includeme_call');
}
Desigur, aș recomanda și instalarea plugin-ului pentru a beneficia de actualizări. https://wordpress.org/plugins/include-me/
