2012-06-08 22 views
15

Tengo una ramita variable html. Para mostrarlo en una plantilla de rama, hago {{html}}.Variables de Twig en twig variable

esa variable se parece a:

<div>{{region_top}}</div><div>{{region_center}}</div>

region_* es una variable también. Cuando Twig analiza mi variable html, no analiza las variables internas (regiones).

¿Qué debo hacer?

+0

Al principio aceptar respuestas a sus preguntas anteriores ... – jkucharovic

+1

Usted Wright, lo siento por eso – Meliborn

Respuesta

24

Tengo twig variable html. Para mostrarlo en la plantilla twig, hago {{html}}. Esa variable se parece a {{region_top}} {{region_center}}. region_ * es también variables. Cuando twig analiza mi variable html, no analiza las variables internas (regiones). ¿Qué puedo hacer?

Twig toma sus cadenas como una cadena literal, lo que significa que verá el contenido de la variable, escapó. Si usted quiere que sea capaz de mostrar {{}} region_top así, lo recomiendo algo como esto:

{{html|replace({'{{region_top}}': region_top, '{{region_center}}': region_center})}} 

Si el contenido de la variable de HTML también es dinámico (lo que significa que puede contener algo más que esas dos variables), escribiría un plugin twig que puede hacer lo que quieras. Escribir complementos es bastante fácil de hacer.

EDIT: Aquí está la extensión que acabo de terminar de escribir.

EDIT 2: La extensión ahora usa el entorno para representar la cadena, por lo que evalúa la cadena, en lugar de simplemente reemplazar las variables. Esto significa que su variable puede contener cualquier cosa que pueda contener una plantilla, y Twig misma la renderizará y escapará. Soy increíble.

<?php 

/** 
* A twig extension that will add an "evaluate" filter, for dynamic evaluation. 
*/ 
class EvaluateExtension extends \Twig_Extension { 
    /** 
    * Attaches the innervars filter to the Twig Environment. 
    * 
    * @return array 
    */ 
    public function getFilters() { 
     return array(
      'evaluate' => new \Twig_Filter_Method($this, 'evaluate', array(
       'needs_environment' => true, 
       'needs_context' => true, 
       'is_safe' => array(
        'evaluate' => true 
       ) 
      )) 
     ); 
    } 

    /** 
    * This function will evaluate $string through the $environment, and return its results. 
    * 
    * @param array $context 
    * @param string $string 
    */ 
    public function evaluate(\Twig_Environment $environment, $context, $string) { 
     $loader = $environment->getLoader(); 

     $parsed = $this->parseString($environment, $context, $string); 

     $environment->setLoader($loader); 
     return $parsed; 
    } 

    /** 
    * Sets the parser for the environment to Twig_Loader_String, and parsed the string $string. 
    * 
    * @param \Twig_Environment $environment 
    * @param array $context 
    * @param string $string 
    * @return string 
    */ 
    protected function parseString(\Twig_Environment $environment, $context, $string) { 
     $environment->setLoader(new \Twig_Loader_String()); 
     return $environment->render($string, $context); 
    } 

    /** 
    * Returns the name of this extension. 
    * 
    * @return string 
    */ 
    public function getName() { 
     return 'evaluate'; 
    } 
} 

Ejemplo de uso:

$twig_environment->addExtension(new EvaluateExtension()); 

En la plantilla:

{% set var = 'inner variable' %} 
{{'this is a string with an {{var}}'|evaluate}} 
+1

¿Complemento o extensión? – Meliborn

+0

¿Quizás reemplazar el filtro puede usar como preg_replace con marcador de posición? Algo así {{html | replace ({'{$ 1}}': $ 1})}} No tengo idea de qué debería hacer el complemento :( – Meliborn

+0

@Meliborn Me refiero a una extensión. Acabo de verificar, pero parece No puedo obtener el valor de una variable de una extensión, por extraño que parezca. Seguiré buscando: podría necesitar algo como esto yo mismo. –

4

Una opción es hacer que sus plantillas como cadenas. Puede hacerlo de esta manera:

$env = new \Twig_Environment(new \Twig_Loader_String()); 
echo $env->render(
    "Hello {{ name }}", 
    array("name" => "World") 
); 

Lo dejo a usted para decidir exactamente cómo estructurar su código para hacer este trabajo, pero podría ser algo como esto: 1) Recuperar el texto de la plantilla interior que contiene las variables que no están siendo reemplazadas. 2) Renderice ese texto interno de plantilla en una variable $ html. Asegúrate de pasar cualquier vars que necesites. 3) Renderice su plantilla original que contiene {{html}}. Asegúrese de pasar en 'html' => $ html en la matriz VARs

14

Ver http://twig.sensiolabs.org/doc/functions/template_from_string.html

Parece que esta frecuencia se perdió ya que la mayoría de la gente piensa (y la búsqueda de) "eval" cuando se esperaba un filtro/función para evaluar en el idioma actual en el que están redactando. Plantilla de cadena no es la primera consulta de búsqueda que se le viene a la mente.

+0

rocking - aprendí algo nuevo aquí. Gracias – ejuhjav