Shortcode siempre se muestra en la parte superior de la página
Estoy usando un shortcode para obtener diferentes loops a través de loops-name.php. Por alguna razón, siempre aparece en la parte superior de la página. Investigué y encontré que usar echo en lugar de return causa ese problema, pero en mi código no estoy usando echo. Aquí está el shortcode:
// configuración del shortcode para su uso
function friendly_loop_shortcode( $atts, $content = null ) {
extract( shortcode_atts( array(
'category' => '',
'module' => ''
), $atts ) );
include(locate_template('loop-'.$module.'.php'));
}
¿Alguna idea de por qué está sucediendo esto?

Puedes almacenar en búfer la salida de esta manera:
ob_start();
include(locate_template('loop-'.$module.'.php'));
return ob_get_clean();
EDITO. Probé esto y funcionó bien.
function friendly_loop_shortcode( $atts, $content = null ) {
extract( shortcode_atts( array(
'category' => '',
'module' => ''
), $atts ) );
ob_start();
include(locate_template('loop-'.$module.'.php'));
$output = ob_get_clean();
//print $output; // depuración
return $output;
}
if (!is_admin()) {
add_shortcode('test', 'friendly_loop_shortcode' );
}

No utilices el buffer de salida si existen otras alternativas.

Tu archivo incluido está esencialmente haciendo echo de HTML. Por ejemplo:
<?php
//Algo de PHP
echo 'test';
//Más PHP
?>
Es lo mismo que:
<?php
//Algo de PHP
?>
test
<?php
//Más PHP
?>
Ambos se imprimen inmediatamente en lugar de retornarse. Como se imprimen, aparecen antes del contenido de la página. Necesitas retornar algo para que se incluya en el contenido.
Como señaló @RutwickGangurde - es inusual incluir un archivo de plantilla en un shortcode.

Gracias, no lo sabía. ¿Entonces necesito poner todo en una variable y retornarla? En cuanto a incluir un archivo de plantilla - bueno, quiero hacerlo lo más fácil posible para los usuarios del tema personalizar el tema y tener un archivo de shortcode enorme anidado lejos del directorio raíz del tema no es realmente ideal para ellos.

"bueno, quiero hacerlo lo más fácil posible para los usuarios del tema personalizar el tema" - ¿Cuántas capas de abstracción son necesarias? Tienes un archivo de plantilla personalizado dentro de un shortcode. No veo cómo eso facilita las cosas para los usuarios. Si quieres proporcionar la capacidad de añadir contenido estático a todas las entradas, simplemente define un dynamic_sidebar()
dentro del Loop, y permite que los usuarios añadan Widgets.

La mayoría de los usuarios del tema no apreciarán tener que revisar un archivo enorme de shortcodes para cambiar una simple clase CSS en el frontend. Si divido todo usando el sistema estándar de loop-name.php, les resultará mucho más rápido encontrar lo que necesitan. No es lo ideal, pero tengo que mantenerlos contentos ;)

Esta es la respuesta correcta, porque la causa del problema fue un "echo" indirecto del HTML, en lugar de construir el HTML en una variable y "return" al final de la función. En la documentación de WordPress, puedes encontrar esta advertencia: *** Recuerda usar return y no echo - cualquier cosa que se haga echo será enviada al navegador, pero no aparecerá en el lugar correcto de la página.***
