2009-01-13 6 views
7

Encontré un par de formas de manejar la recursión en Smarty, principalmente basada en incluir plantillas en sí mismas, lo que parece una pérdida de recursos ridícula. Encontré una solución, por Messju en Smarty que parecía ser la correcta, pero no es compatible y falla en la última versión de smarty :(¿Cuál es la mejor forma de manejar la recursión en smarty?

Para las personas que preguntan: Lo que quiero que Smarty imprima es una discusión hilo que se define por un conjunto de entradas. Si una entrada tiene una o más respuestas, aquellos enumerados como los niños a dicha entrada en una matriz, y así sucesivamente.

array(
    array(
     'id'=>0, 
     'headline'=>"My parent headline", 
     'body' =>"My parent body", 
     'children'=>array(
      array(
       'id'=>1, 
       'headline'=>"My firstChild headline", 
       'body' =>"My firstChild body", 
       'children'=>array() 
      ), 
      array(
       'id'=>2, 
       'headline'=>"My secondChild headline", 
       'body' =>"My secondChild body", 
       'children'=>array() 
      ) 
     ) 
    ), 
); 

La matriz anidada tiene una profundidad arbitraria, y cada entrada tendrá un número arbitrario de hijos. Para mí, esto es algo que quiero hacer dentro del alcance de la plantilla, ya que la considero pura lógica de visualización. No quiero tener que manejar HTML o algún tipo de HTML. marcadores de posición fuera de la modelo.

Quiero Smarty para imprimir esto como anidados listas:

<ul> 
    <li> 
     <h1>My parent headline</h1> 
     <p>My parent body</p> 
     <ul> 
      <li> 
       <h1>My firstChild headline</h1> 
       <p>My firstChild body</p> 
      </li> 
      <li> 
       <h1>My secondChild headline</h1> 
       <p>My secondChild body</p> 
      </li> 
     </ul> 
    </li> 
</ul> 

estoy empezando a darse cuenta de que esto podría ser un problema muy, caso por caso, por lo que figura que voy a escribir un plugin Smarty para manejar esto específicamente, aunque preferiría tener una solución completa.

¿Hay alguna manera?

Respuesta

6

"Con el fin de entender la recursividad, primero hay que entender la recursividad ..."

Es broma. Esto debería hacer lo que desee:

<?php 
/* 
* Smarty plugin 
* ————————————————————- 
* File:  function.recurse_array.php 
* Type:  function 
* Name:  recurse_array 
* Purpose: prints out elements of an array recursively 
* ————————————————————- 
*/ 

function smarty_function_recurse_array($params, &$smarty) 
{ 

if (is_array($params['array']) && count($params['array']) > 0) { 
    $markup = ''; 

    $markup .= '<ul>'; 

    foreach ($params['array'] as $element) { 
     $markup .= '<li>'; 

     $markup .= '<h1>' . $element['headline'] . '</h1>'; 
     $markup .= '<p>' . $element['body'] . '</p>'; 

     if (isset($element['children'])) { 
     $markup .= smarty_function_recurse_array(array('array' => $element['children']), $smarty); 
     } 

     $markup .= '</li>'; 
    } 

    $markup.= '</ul>'; 

    return $markup; 

} else { 
    return 'not array'; 
} 
} 

Coloque el archivo en la carpeta smarty/plugins. Asignar la matriz a Smarty luego llamarlo en la plantilla de este modo:

{recurse_array array=$data} 

Aquí hay buen tutorial para hacer las funciones de Smarty personalizados:

Creating Custom Smarty Functions

ser consciente de la dependencia que este ejemplo tiene en su estructura de datos subyacente. Además, tenga en cuenta que un conjunto de datos inusualmente largo o profundamente anidado podría ser realmente lento. Administre su complejidad, mantenga las cosas bien documentadas, y debería estar bien. ¡Buena suerte!

-3

La mejor manera es no hacerlo.

Se supone que Smarty es simple. Esto no suena.

+3

Piénselo de esta manera, la aplicación necesita mostrar una lista anidada arbitrariamente de cosas. Hay complejidad allí. Necesitas administrar la complejidad. Tiene sentido poner lo que esencialmente es lógica de visualización (loop en una matriz y spit out markup) en la plantilla. El hecho de ser recursividad no lo convierte en malvado. – GloryFish

+0

Lo suficiente, pero en comparación con hacer recursividad con una función única, una solución inteligente será intrincada. –

0

Es posible que desee considerar la creación de una función personalizada/modificador/complemento para smarty. Pase la matriz a la función personalizada junto con la definición de la plantilla que debe usar la función. Si es así de simple, solo inserte un texto en un lugar determinado, cargue la plantilla dentro de la función y en PHP trabaje con la plantilla usando regexes/str_replace/...

O hágalo directamente en PHP sin usar plantillas smarty, porque todo lo que necesita son etiquetas h1, ul, li y p, y para cambiar el diseño, use CSS.

O si su preocupación es la sobrecarga con la apertura y cierre de archivos en Smarty, estime cuál es la cantidad de niveles en el 90% de los casos y cree una plantilla que cubra esos 90%. Para el resto utiliza la recursividad mediante la inclusión de la propia plantilla ...

14

Con Smarty 3, esto se puede hacer usando {función}. El siguiente código producirá la salida requerida.

{function name=printList} 
<ul> 
    {foreach $items as $item} 
    <li> 
     <h1>{$item['headline']}</h1> 
     <p>{$item['body']}</p> 
     {if $item['children']} 
      {call name=printList items=$item['children']} 
     {/if} 
    </li> 
    {/foreach} 
</ul> 
{/function} 

{call name=printList items=$comments} 

Más información se puede encontrar en el docs.

Nota al margen: El hecho de que algo sea complejo o recursivo no significa que no pueda estar dentro de una plantilla. Por Dios, la estructura HTML ul-li es naturalmente recursiva y al esconderla o moverla a otra parte (solo porque es demasiado compleja para una plantilla) está introduciendo una complejidad extra en la aplicación.

+0

¡Fantástico! Sé que es una vieja pregunta, pero este enfoque es brillante. +1 –

Cuestiones relacionadas