XCSS : reinventar la rueda del CSS dinámico

En Febrero del 2008 diseñé una clase llamada XCS que utilizaba PHP para generar CSS dinámicamente, con la posibilidad de utilizar variables dentro del mismo fichero de reglas de estilo para hacer webs con contenido modificable fácilmente.

Hace poco he encontrado el “primer framework CSS orientado a objetos” como lo nombra a sí mismo Anton Pawlik su autor, http://xcss.antpaw.org/ y que hace precisamente eso,…sin embargo ha tenido mucho éxito 🙂

A pesar de su sencillez, (la clase principal no es muy complicada) no se diferencia demasiado de la que escribí basándome en otra al mismo tiempo…aunque no la he llegado a usar como programador php

Complementos de software libre para optimización de webs

Page Speed for the people!

Hace tiempo escribí un artículo sobre complementos de optimización, pero en ese momento no existía Page Speed,  si queréis saber lo que es podéis (si sabéis inglés) escuchar al autor en este vídeo:

Para instarlo ir a la web de Page Speed, previamente debéis haber instalado en vuestro Firefox el componente Firebug.

Es una herramienta genial para conocer los consejos de optimización más técnicos, como por ejemplo, usar diferentes dominios y subdominios para cada parte de la web, por ejemplo, podemos crear un directorio media y hacer un subdominio para alojar allí el contenido, o mejor, uno para cada tipo de multimedia: video.dominio.es, img.dominio.com, etc. , además explica brevemente por qué vuestra página carga tan lenta, y qué podéis hacer para solucionarlo. Si queréis ver algún ejemplo podéis pasaros por la web de un programador php. 🙂

Recomendado! 5 stars jeje

Prioridad lineal de los procesos de una aplicación web

Cuando estamos manteniendo una aplicación web suele ocurrir que el usuario final nos pide cambios que rompen el esquema inicial de la misma, es decir, se quieren saltar todas las reglas del diseño en el que nos habíamos “partido los cuernos” de forma que fuera todo fácilmente mantenible y estable asi como escalable.

En estos momentos tenemos dos opciones: cabrearnos mucho y quejarnos con el usuario para que lo haga a “nuestra manera o carretera”, o bien, mucho mejor, que la prioridad forme parte de todo este asunto.

Es ahora cuando decidimos que la segunda opción favorece nuestro trabajo de forma que podemos ir todavía más un paso adelante, es decir, si después de realizar todas las tareas necesarias para generar una página de una aplicación el contenido generado requiere un cambio de última hora, podemos utilizar una prioridad para construir/destruir dicho contenido. Un ejemplo es utilizar CSS, la prioridad se establece con la opción “!important” ,entonces, si en el HTML de nuestro primer diseño de la web tenemos un listado de hoteles y necesitamos que en uno de los hoteles del listado se muestre una división de forma distinta, simplemente vamos a permitir que en el editor HTML WYSYWYG se puedan introducir etiquetas de estilo: <style> [ extended_valid_elements: “style” en tinymce ]y ahora vamos a reescribir la regla donde se necesita que se muestre de otra forma el contenido, en lugar de cambiar toda la lógica de la programación, entonces ,usando “!important” al lado de las reglas, por ejemplo para el ancho :

<style> #midivision { width: 350px !important;} </style>

de esa forma le damos prioridad a esta regla, lo mismo se puede hacer con javascript y el argumento “defer” de la etiqueta <script>, y lo mismo se puede utilizar en PHP si especificamos el orden de carga de las clases, etc etc.

Tratamiento dinámico avanzado con etiquetas entre dominios



Para compartir el uso de etiquetas entre varios dominios lo que se suele hacer es compartir una base de datos en un servidor y utilizar varias aplicaciones que comparten modelos de datos y modifican las vistas (visualizadores) para mostrar los resultados en una sinergía creada por los usuarios que rellenan artículos, contenido, noticias, productos, etc. y establecen las etiquetas asociadas a toda esta información…

La función que va en la clase tags del modelo de datos de zenphp es:

 /**
  * Devuelve un array con todos los tags de todas las tablas que coinciden con $nombre
  **@TODO: Es inestable, no carga bien los modelos de datos que no estuvieran ya cargados...
  *
  * @param str $nombre
  * @param str $modelos
  * @return array
  */
 function obtener_lista($nombre="",$modelos=""){
  $nombre    = str_replace("_","-",$nombre);
  $modelos   = empty($modelos)?array("noticias","contenidos"):split(",",$modelos);
  if (!is_array($modelos)) return false;
  $etiquetas = array();
  foreach ($modelos as $modelo){
   $unset =false;
   if (!$this->padre->$modelo instanceof zen_modelo_datos) {
   	if (!zen___importar_modelos($this->padre,$modelo)) {
   		continue;
   	} else {
   		$unset = true;
   	}
   }
   $c = split(",",$this->padre->$modelo->campos);
   $this->padre->$modelo->poner_campos_al_modelo();
   $r = $this->padre->$modelo->obtener($c[0].",tags");
   $n = count($r);
   for ($i=0; $i<$n; $i++){
   	$tags = str_replace(array(" ,",", "),",",$r[$i]['tags']);
    $tags = split(",",$tags);
    foreach ($tags as $tag){
     $tag = html_entity_decode($tag);
     if (empty($nombre)){ //No buscamos un tag en concreto sino todos:
      if (!in_array($tag,$etiquetas)) //Insertar en la lista
       $etiquetas[] = $tag;
      continue;
     }
     if (zen_codifica_nombre_para_url($tag)==
    	zen_codifica_nombre_para_url($nombre))
     {
      if (!in_array($r[$i][$c[0]],$etiquetas)){
     	array_push($etiquetas,array(
     	 "modelo"=> $modelo,
     	 "id"   =>  $r[$i][$c[0]]
        ));
      } //comprobacion de si se estaba repetida
     } //comprobacion de si es la buscada
    } //bucle foreach de tags
   } //bucle for que recorre todos los tags de este campo
   if ($unset) unset($this->padre->$modelo);
  } //bucle for que recorre todos los modelos especificados
  return $etiquetas;
 }

Para utilizar una función dinámica que un visualizador (html_tags extends zen_html_modelo_datos) interprete usando diferentes plantillas para cada dominio podemos usar la siguiente :

 /**
  * Mostrara una pagina con un listado de tags, que enlazan a los distintos dominios,
  * se especifica el $dominio para ver cual de los contenidos han de rellenarse
  *
  * @param str $tag
  * @param str $dominio
  */
 function ver($tag,$dominio=ZF_SITIO_WEB){
  //Intentemos encontrar el tag
  $tags = $this->padre->obtener_lista($tag);
  $p = new zen_plantilla();
 // if (!count($tags)) die(sprintf("no hay ningun elemento con el tag %s",$tag));//header("Location: ".ZF_SITIO_WEB);
  $r['tag'] = str_replace("_","-",zen_sanar($tag));
  $r['enlaces'] = "";
 
  foreach ($tags as $tag){
   switch ($tag['modelo']){
   	case 'noticias': //Noticias a la web del grupo (corporativa)
   	 $tit = $this->padre->padre->noticias->obtener_campo($tag['id'],"titular");
   	 $r['enlaces'] .= 'Noticia: <a href="'.ZF_SITIO_WEB.'noticias/ver/'.$tag['id'].'/'.zen_codifica_nombre_para_url($tit).
   	 	'/">'.$tit.'</a><br>';
   	 break;
   	case 'contenidos': //Presentacion.. (informacion corporativa)
   	 $tit = $this->padre->padre->contenidos->obtener_campo($tag['id'],"nombre");
   	 $zona= $this->padre->padre->contenidos->obtener_campo($tag['id'],"zona");
   	 $r['enlaces'] .= 'Presentaci&oacute;n: <a href="'.ZF_SITIO_WEB.'presentacion/'.
   	 	$tag['id'].'/'.zen_codifica_nombre_para_url($tit).
   	 	'/">'.$tit.'</a><br>';
   	 break;
   }
  }
  $this->padre->padre->contenido['contenido'] = $p->contenido_reemplaza("etiquetas/indice.html",$r);
  switch ($dominio){
   case ZF_SITIO_WEB:
    $this->
    $this->padre->padre->contenido['columna_izda1'] = $this->listar();
    $this->padre->padre->html->mostrar_web("Etiqueta ".
  	 zen_sanar($r['tag']),"sel_inicio","cab_contacto.html","rut_etiqueta.html"); 
  	break;
   default:
    //$titulo,$menu,$ruta="",$col_izda="indice"
    $this->padre->padre->html->mostrar_web("Etiqueta ".$tag,"sel_indice","rut_etiqueta.html","indice"); 
  	break;
  } 
 } //fin-ver

Automatizando Flash mediante XHTML, DHTML,ActionScript y PHP

Primero deberemos preparar el Flash, con un poco de código en ActionScript para cargar el XML y guardar las variables Flash en el nodo root de la película de forma que así activaremos las animaciones

Después diseñamos el XML como plantilla para zenphp:

así como el JavaScript en otra plantilla, que escribirá el objeto Flash con las variables mediante PHP

sólo queda el PHP, una función simplísima para escribir los contenidos:

Y ya tenemos funcionando el conjunto para cualquier entrada de la base de datos:

Encontrar el equilibrio en las cosas pequeñas

Siendo detallista y equilibrado encontraremos que nuestro trabajo se ha convertido en algo sumamente sencillo de mantener.

El caso más fundamental de lo que estoy hablando es cuando un cliente nos pide un nuevo cambio que requiere modificar, en este caso añadir un campo nuevo de imagen de miniatura a una tabla de noticias y,bien, ahora tenemos que añadirlo en la interfaz de administración además de en la BD y en el cliente que habíamos escrito…

Sabemos que podemos implementar la lógica de administración fácilmente haciendo copio y pego de la parte del formulario de edición de la noticia cambiando el nombre por el del campo de la imagen ,guardado de ficheros, procesamiento de imágenes “thumbs” , etc.

Lo que debemos recordar es que podemos encontrar el equilibrio en el funcionamiento por medio de las sentencias IF de SQL, de modo que si ya teníamos un campo imagen y ahora lo que necesitamos es mostrar una miniatura pero no queremos cambiar el resto, simplemente modificamos la línea en la que se nombran los campos para realizar las operaciones de la siguiente forma:

si antes se hacia un “Select imagen from noticias” ,ahora sólo tenemos que cambiar “imagen” por

IF(miniatura=”,imagen,miniatura) as imagen

de forma que el resto de la lógica del programa se mantiene intacta, sólo hemos hecho un cambio más las operaciones básicas para administrar los datos con el campo 😉

Ahora sólo queda relajarse sabiendo que todo funciona sin quebrarnos demasiado la cabeza jeje

Howto: filtrar datos de forma avanzada pero pensando como un principiante

En principio, parece que el título del post es algo de lo más paradójico, pero nada más lejos de la realidad, en zenphp siempre hay un Joker, y éstos son los trucos que enseño en este blog, triquiñuelas rápidas y complejas pero fáciles de entender y modificar en poco tiempo.

Continue reading

Como hacer la semántica web fácil con zenphp

Semántica web

Si tenemos nuestra aplicación web montada, lo único que tenemosque hacer es configurar los activadores (rutas de .htaccess de Apache) de las acciones (funciones PHP) de los modelos (clases PHP que extienden de zen_modelo_datos) de datos o las funciones de los visualizadores (clases PHP) de forma que podemos incluso crear nuestra propia gramática: loquesea.es/hablar/con/Manolo –> nos contactaría con Manolo 😉

Ejemplo

Como siempre, veamos un ejemplo para comprender mejor la idea:

Tenemos una aplicación (zen_aplicacion) instanciada en index.php con la variable $app , ahora ,dentro de esta hay un visualizador por defecto llamado html_aplicacion en $app->html, bien, pues ahora sólo tenemos que decirle a Apache que nos redirija las entradas de direcciones con un .html al final, a las funciones de $app->html , como por ejemplo: Una típica función para ver un producto:

* En tu .htaccess (después de poner “Options +FollowSymLinks” y “RewriteEngine on” ):

RewriteRule ^productos\/(.*)\.html index.php/ver_producto/$1/

Con esta regla se llama a index.php donde se instancia $app y se llama a $app->enrutador->delegar() que analiza el resto de la dirección, es decir, productos/fichero.html…de forma que llama a la función productos ,si no existe llama al modelo con nombre productos, en nuestro caso es una función del visualizador de la aplicación (más sencillo),

Código

* Esto es lo único que tiene la función

echo $this->plantilla->devolver_contenido(“productos/”.zen_sanar($datos[1]).”.html”);

si queréis ser más profesionales, crear una plantilla HTML y meterle los datos usando las #etiquetas# ya explicadas en otros posts, asi como hacer comprobaciones de existencia del fichero .HTML y poner una plantilla tipo producto_inexistente.html si no se encuentra… (típico)

$p = new zen_plantilla();
$this->c =& $this->padre->padre->contenido; //array de contenido de la web
if ($p->cargar(“productos/”.zen_sanar($datos[1]).”.html”))
$this->c[‘contenido’] = $p->devolver_contenido(“productos/”.zen_sanar($datos[1]).”.html”);
else
$this->c[‘contenido’] = $p->devolver_contenido(“productos/no_encontrado.html”);
parent::index(); //Muestra la plantilla base_web.html y reemplaza etiquetas, etc.

Y así tendréis algo como lo siguiente:

http://www.empresayjuventud.com/productos/frescos/sandias.html

Seguramente ,se puede hacer mucho más fácil, pero ,también seguramente habrá alguien por ahi que lo escriba, saludos!
El conjunto de administración está siendo terminado, espero poder publicarlo pronto…

Sobre compatibilidades entre versiones de PHP y zenphp

Hace un tiempo que cambié la versión de mi host dedicado de PHP4.2 a 5.2.6 y zenphp no ha tenido ningún problema para funcionar. Sólo un pequeño detalle a tener en cuenta con el fichero .htaccess…

Cuando escribimos redirecciones como por ejemplo:

AddDefaultCharset UTF-8
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^noticias index.php/noticias
RewriteRule ^noticia\/(.*) index.php/noticias/leer/$1

en la que queremos que las www.midominio.com/noticias se redirija a www.midominio.com/index.php/noticias/ para encontrar el controlador por defecto, en PHP5 ahora se usa en lugar de <$_SERVER[‘REQUEST_URI’]> el parámetro <$_SERVER[‘PHP_SELF’]> dentro de

zenphp/clases/clase_zen_enrutador.php

de forma que estas redirecciones más complejas sean bien encauzadas sin tener que reescribir el módulo del enrutador que proporciona el framework…recordar que se puede escribir un enrutador y asociarlo a cualquiera de la s aplicaciones que estemos usando en el sistema y lanzarlo por medio de una función tipo “delegar()”.

Seguimos informando!

Detalles del Modelo Visualizador VS MVC

Acabo de estar mirando el nuevo modelo de datos de Joomla 1.5 junto con su controladores y vistas…es interesante sin embargo complicado y necesitas tener el manual cerca (a “mano” :D) porque no sabes nada de nada al estar dentro de una vista…si estás en una vista tipo “blog” de una categoría, cómo puedes conseguir la sección a la que pertenece? En algunos foros se discute el tema, acabando por hacer un nuevo y completo módulo o extensión también llamado para cubrir las necesidades…sólo por necesitar un identificador? …como veis parece absurdo tener una división que no te da libertad y crea más confusión…

En zenphp está el modelo de datos donde están todos los datos que está comunicado con punteros con el resto de modelos de la aplicación y por otro lado está, asociado al modelo ,el visualizador, nunca perdemos nada de vista y todo es parametrizable y accesible fácilmente, casi no tenemos ni que usar el manual o la documentación…veis la pauta? notais la diferencia? ahi radica la potencia de hacer algo simple y que funciona…

Saludos!