Solucion para variables php en criterios de bucles

He encontrado maneras de utilizar algo de php en criterios de bucles. No se
puede hacer todo, ni es muy elegante, pero...

Date: Sat, 21 Feb 2004 12:09:48 +0100
A las buenas. Mi problema es...
Puedo hacer funcionar algo así:

{id_document=<? echo $docu ?>}

¿Cómo?

La forma de establecer un criterio de un bucle inferior desde un baliza
previa sería:

En mes_fonctions.php3:

function set_var_entorno($text, $var, &$contexte) {
    $contexte["$var"] = "$text";
    return;
}

En el esqueleto, (sin que importe la profundidad del bucle donde se utiliza
el criterio):

<BOUCLE_forum(FORUMS) {id_article}...>
    ...
    [(#ID_FORUM|set_var_entorno{'nombre_variable', $contexte})]

    <BOUCLE_discusion(FORUMS)...>
        ....
        <BOUCLE_respuestas(FORUMS) {id_forum=$nombre_variable}...>
            ....
        </BOUCLE_respuestas>
        ....
    </BOUCLE_discusion>
</BOUCLE_forum>

Pero esto no sirve para elevar variables de un bucle inferior a otro
superior, ya que los cambios de contexto se pierden con el fin del bucle en
cuestión, con lo que dichos cambios no son visibles a nivel superior.

Para poder hacer esto haria falta:

En mes_fonctions.php3:

function set_var_global($text, $var) {
    global $contexto;
    $contexto["$var"] = "$text";
    return;
}

function echo_var_global($void, $var) {
    global $contexto;
    return $contexto["$var"];
}

function set_var_entorno($text, $var, &$contexte) {
    $contexte["$var"] = "$text";
    return;
}

En el esqueleto (ver que funciona para bucles inferiores, aunque sean
recursivos):

<BOUCLE_forum(FORUMS) {id_article}...>
    ....
    En este ejemplo vamos a encontrar el mensaje raiz en un foro del que es
respuesta el mensaje actual
    [(#ID_FORUM|set_var_global{'top'})]
    <BOUCLE_top(FORUMS) {id_enfant}>
        [(#ID_FORUM|set_var_global{'top'})]
        <BOUCLE_ascendente(boucle_top)>
        </BOUCLE_ascendente>
    </BOUCLE_top>

    Notar que aquí el #ID_FORUM no sirve realmente para nada, pero hace
falta alguna baliza para que funcionen los filtros
    [(#ID_FORUM|echo_var_global{'top'}|set_var_entorno{'top', $contexte})]

    <BOUCLE_discusion(FORUMS){id_forum=$top}...>
        ...
    </BOUCLE_discusion>
</BOUCLE_forum>

Para otro tipo de necesidades habría que ver como hacerlo, pero teniendo en
cuenta que los codigos php incrustrados <?php ... ?> se ejecutan en una
pagina de cache en la que todo lo demás es HTML puro (lo generado por SPIP
en tiempo de actualización de cache), y todo lo que pongamos en
mes_fonctions.php3 solo se ejecuta en dichas actualizaciones sin poder
interactuar con el php incrustrado (¡que yo sepa!)

Saludos
JMSE

Hola José,
Hola a tod@s,

Está bien, bien interesante, tu propuesta!
Y yo la encuentro bastante elegante: generar nuevas variables en el
contexto de spip. excelente!

No domino el php como entender bien toda la sutileza del '&' en
&$contexte, pero antes de entender, estoy probando aplicar tu propuesta
como 'receta de cocina', para hacer un calendario. He logrado mal que
bien comprobar que tu propuesta funciona, pero después me surgen
problemas con los criterios de fecha.

Dos preguntas:
1/ tu propuesta permite recuperar el valor de una baliza. Como sería
una variante de tu función set_var_entorno para poder recuperar una
variable pasada en la URL? Como el archivo de la cache depende de la
URL, debería ser posible y útil transferir esas variables al contexto
spip.

2/ En otros casos puede ser útil "forzar" una variable del contexto. Por
ejemplo, recuperas una fecha, y en 3 niveles inferiores de bucle, para
utilizar un criterio date_relatif, quieres que la fecha de contexto no
sea la que deduce spip, sino aquella recuperada anteriormente.
Con tu set_var_entorno puedes pasar una variable $fecha_ref, pero luego
sería bueno una funcion set_varA_to_varB, que permita transferir los
datos de $fecha_ref a $date

Procuraré explorar el manejo de referencias y punteros en php para ver
si avanzo. Todo esto merecería una contrib para manipulación de
variables de contexto!!

Saludos,

daniel

Le sam 17/04/2004 à 05:05, José María Sánchez Estévez a écrit :

He encontrado maneras de utilizar algo de php en criterios de bucles. No se
puede hacer todo, ni es muy elegante, pero...

> Date: Sat, 21 Feb 2004 12:09:48 +0100
> A las buenas. Mi problema es...
> Puedo hacer funcionar algo así:
>
> {id_document=<? echo $docu ?>}
>
> ¿Cómo?

La forma de establecer un criterio de un bucle inferior desde un baliza
previa sería:

En mes_fonctions.php3:

function set_var_entorno($text, $var, &$contexte) {
    $contexte["$var"] = "$text";
    return;
}

En el esqueleto, (sin que importe la profundidad del bucle donde se utiliza
el criterio):

<BOUCLE_forum(FORUMS) {id_article}...>
    ...
    [(#ID_FORUM|set_var_entorno{'nombre_variable', $contexte})]

    <BOUCLE_discusion(FORUMS)...>
        ....
        <BOUCLE_respuestas(FORUMS) {id_forum=$nombre_variable}...>
            ....
        </BOUCLE_respuestas>
        ....
    </BOUCLE_discusion>
</BOUCLE_forum>

Pero esto no sirve para elevar variables de un bucle inferior a otro
superior, ya que los cambios de contexto se pierden con el fin del bucle en
cuestión, con lo que dichos cambios no son visibles a nivel superior.

Para poder hacer esto haria falta:

En mes_fonctions.php3:

function set_var_global($text, $var) {
    global $contexto;
    $contexto["$var"] = "$text";
    return;
}

function echo_var_global($void, $var) {
    global $contexto;
    return $contexto["$var"];
}

function set_var_entorno($text, $var, &$contexte) {
    $contexte["$var"] = "$text";
    return;
}

En el esqueleto (ver que funciona para bucles inferiores, aunque sean
recursivos):

<BOUCLE_forum(FORUMS) {id_article}...>
    ....
    En este ejemplo vamos a encontrar el mensaje raiz en un foro del que es
respuesta el mensaje actual
    [(#ID_FORUM|set_var_global{'top'})]
    <BOUCLE_top(FORUMS) {id_enfant}>
        [(#ID_FORUM|set_var_global{'top'})]
        <BOUCLE_ascendente(boucle_top)>
        </BOUCLE_ascendente>
    </BOUCLE_top>

    Notar que aquí el #ID_FORUM no sirve realmente para nada, pero hace
falta alguna baliza para que funcionen los filtros
    [(#ID_FORUM|echo_var_global{'top'}|set_var_entorno{'top', $contexte})]

    <BOUCLE_discusion(FORUMS){id_forum=$top}...>
        ...
    </BOUCLE_discusion>
</BOUCLE_forum>

Para otro tipo de necesidades habría que ver como hacerlo, pero teniendo en
cuenta que los codigos php incrustrados <?php ... ?> se ejecutan en una
pagina de cache en la que todo lo demás es HTML puro (lo generado por SPIP
en tiempo de actualización de cache), y todo lo que pongamos en
mes_fonctions.php3 solo se ejecuta en dichas actualizaciones sin poder
interactuar con el php incrustrado (¡que yo sepa!)

Saludos
JMSE

_______________________________________________
Spip-es@rezo.net - http://listes.rezo.net/mailman/listinfo/spip-es

Hola a todas. Respondo en linea

-----Mensaje original-----
De: Daniel [mailto:dani@belvil.net]
Enviado el: miércoles, 21 de abril de 2004 11:07

No domino el php como entender bien toda la sutileza del '&' en
&$contexte, pero antes de entender, estoy probando aplicar tu propuesta
como 'receta de cocina', para hacer un calendario. He logrado mal que
bien comprobar que tu propuesta funciona, pero después me surgen
problemas con los criterios de fecha.

En PHP por defecto los parámetros de funciones se reciben por valor (la
función trabaja con una copia), con lo que cualquier modificación que se
haga se pierde al terminar la función. Para que la función trabaje con la
variable original del llamante se debe prefijar con &, con lo que las
modificaciones 'salen' de la función.

Dos preguntas:
1/ tu propuesta permite recuperar el valor de una baliza. Como sería
una variante de tu función set_var_entorno para poder recuperar una
variable pasada en la URL? Como el archivo de la cache depende de la
URL, debería ser posible y útil transferir esas variables al contexto
spip.

Se puede hacer. En mes_fonctions.php3:

function set_var_entorno($text, $var, &$contexte, $value='') {
    $contexte["$var"] = $value ? "$value" : "$text";
    return;
}

function set_var_entorno_from_get($void, $var, &$contexte) {
    return set_var_entorno($void, $var, $contexte, $_GET[$var]);
}

En el esqueleto, por ejemplo para recuperar la variable 'fecha' de la URL y
utilizarla para seleccionar articulos de dicha fecha:

La baliza solo sirve para que funcione el filtro
[(#NOM_SITE_SPIP|set_var_entorno_from_get{'fecha', $contexte})]

<BOUCLE_articulos(ARTICLES){date==^$fecha} {par date} {inverse}>
...

2/ En otros casos puede ser útil "forzar" una variable del contexto. Por
ejemplo, recuperas una fecha, y en 3 niveles inferiores de bucle, para
utilizar un criterio date_relatif, quieres que la fecha de contexto no
sea la que deduce spip, sino aquella recuperada anteriormente.
Con tu set_var_entorno puedes pasar una variable $fecha_ref, pero luego
sería bueno una funcion set_varA_to_varB, que permita transferir los
datos de $fecha_ref a $date

Creo que no es adecuado modificar las balizas SPIP (efectos indeseados no
controlables y posibles problemas con posteriores versiones de SPIP) y creo
que hay que buscar alternativas para no hacerlo. En cualquier caso, (yo no
lo haria) se puede intentar (yo no lo he probado):

En mes_fonctions.php3:
function set_varA_to_varB($void, $source, $target, &$contexte) {
    $contexte["$target"] = $contexte["$source"];
    return;
}

En el esqueleto:
[(#una_baliza_valida|set_varA_to_varB{'fecha', 'date', $contexte})]

En otro orden de cosas, envié el mensaje a spip-es y a una discusión sobre
el asunto en http://www.spip.net/threadspip2015-388.html para ver que
opinión merece, si se ve bien o si se puede hacer algo mejor, con la
intención de formalizar después una spip-contrib más o menos 'consensuada'.
No obstante la unica respuesta ha sido de Daniel, así que lo meteré en
cuanto pueda.

Saludos,
JMSE

Se me ha olvidado comentar una cosa importante en el caso de recuperación de
variables de la URL para criterios de bucle:

No controlo bien como funciona la caché, pero entiendo que hay que forzar el
refresco en la URL para que se vuelva a construir el esqueleto de la cache,
ya que si no las querys a la BD contendrán los criterios anteriores. No
obstante, en una prueba rápida que he hecho funciona bien sin el refresco y
no entiendo por que. Incluso veo que se crea el esqueleto en la cache, pero
no se crea 'html' en los subdirectorios de la cache, que teoricamente son
los que dependen de la URL invocante.

Alguna idea sobre esto, porque hay que aclararlo para poder utilizar la
solución con garantias de que va a ir siempre bien.

Saludos,
JMSE