Estimado señor directo del banco de lo que queda de España, quisiera que atendiese mi petición de que me inyecte liquidez en mi sistema, que es muy sencillo y se compone, básicamente, de una cuenta corriente y mi cartera. Comprenderá que mi situación es insostenible ya que he comprado, cual doncella inocente, pasivos tóxicos -pisos sobrevalorados- y dado que su actuación con otras entidades es similar, confío en que vendrá usted al rescate de una familia con dificultades. Lamentablemente, la culpa de mi situación no la tengo yo, ni los bancos, faltaría más, si no la falta de regulación del mercado y del Gobierno, que debería haberme hecho más inspecciones y dado más consejos paternalistas de lo que adolecen los bancos. Por supuesto, hay gente que no está en ese banal problema llamado falta de liquidez y está en bancarrota, para ellos pido un plan de rescate como el que estoy seguro, dada su sagacidad, está planeando también para sus amadas entidades bancarias. Esas familias se conformarían con soluciones similares a las usuales: que paguen otros. Estoy seguro que su principal preocupación es el país y no sólo bancos ligeros de cascos. Para que reflexione, le hago la misma pregunta que Bertorlt Brech se hacía hace medio siglo: ¿Qué es mayor delito: robar un banco o fundarlo?
Emilio Iglesias
Sevilla
Carta al director extraida de la versión en papel del diario ADN (xpresate).

En algunas ocasiones nos encontramos ante la necesidad de tener que mostrar por pantalla un extracto de un texto largo. Por ejemplo, cuando deseamos mostrar una parte de la última noticia de un blog o mostrar un extracto de la descripción de un producto en una tienda virtual.
La solución aplicada en la mayoría de ocasiones a la hora de cortar un texto (truncar) se reduce a mostrar los x primeros caracteres del mismo. Solución no muy adecuada ya que no se tiene en cuenta si estamos cortando alguna palabras, si estamos cortando alguna etiqueta HTML o si estamos produciendo HTML mal formado (ejemplo: etiquetas sin cerrar; <p>HTML mal formado ya que faltaría el tag </p>).
Obtener un extracto de un texto plano – Versión simple:
// Definimos el texto $_noticia = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; // Obtenemos un extracto de los 150 primeros caracteres $_extracto = substr($_noticia, 0, 150); // Mostramos el extracto por pantalla echo $_extracto; // La salida: // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis n
Obtener un extracto de un texto HTML – Versión simple:
// Definimos el texto $_noticia_html = "<p><strong>Sergio Guerrero está cortando este texto</strong></p>"; // Obtenemos un extracto de los 10 primeros caracteres $_extracto_html = substr($_noticia_html, 0, 10); // Mostramos el extracto por pantalla echo htmlentities($_extracto_html); // La salida: // <p><strong
Como se puede observar en los ejemplos anteriores, esta forma de obtener un extracto de un texto nos puede ocasionar problemas realmente importantes, especialmente cuando cortamos textos con etiquetas HTML.
Una solución más adecuada a este problema la podemos obtener reutilizando funcionalidades implentadas y probadas en algunos Frameworks PHP. En este caso, reutilizaremos una función de CakePHP.
CakePHProot / trunk / cake / x.x.x.x / cake / libs / view / helpers / text.php
Donde x.x.x.x equivale a la versión actual del framework
Para obtener la versión más reciente del código mostrado a continuación, podemos acceder al sistema de control de versiones (trac) de Cake PHP y obtener la última revisión.
/** * Truncates text. * * Cuts a string to the length of $length and replaces the last characters * with the ending if the text is longer than length. * * @param string $text String to truncate. * @param integer $length Length of returned string, including ellipsis. * @param mixed $ending If string, will be used as Ending and appended to the trimmed string. Can also be an associative array that can contain the last three params of this method. * @param boolean $exact If false, $text will not be cut mid-word * @param boolean $considerHtml If true, HTML tags would be handled correctly * @return string Trimmed string. */ function truncate($text, $length = 100, $ending = '...', $exact = true, $considerHtml = false) { if (is_array($ending)) { extract($ending); } if ($considerHtml) { if (mb_strlen(preg_replace('/<.*?>/', '', $text)) <= $length) { return $text; } $totalLength = mb_strlen($ending); $openTags = array(); $truncate = ''; preg_match_all('/(<\/?([\w+]+)[^>]*>)?([^<>]*)/', $text, $tags, PREG_SET_ORDER); foreach ($tags as $tag) { if (!preg_match('/img|br|input|hr|area|base|basefont|col|frame|isindex|link|meta|param/s', $tag[2])) { if (preg_match('/<[\w]+[^>]*>/s', $tag[0])) { array_unshift($openTags, $tag[2]); } else if (preg_match('/<\/([\w]+)[^>]*>/s', $tag[0], $closeTag)) { $pos = array_search($closeTag[1], $openTags); if ($pos !== false) { array_splice($openTags, $pos, 1); } } } $truncate .= $tag[1]; $contentLength = mb_strlen(preg_replace('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', ' ', $tag[3])); if ($contentLength + $totalLength > $length) { $left = $length - $totalLength; $entitiesLength = 0; if (preg_match_all('/&[0-9a-z]{2,8};|&#[0-9]{1,7};|[0-9a-f]{1,6};/i', $tag[3], $entities, PREG_OFFSET_CAPTURE)) { foreach ($entities[0] as $entity) { if ($entity[1] + 1 - $entitiesLength <= $left) { $left--; $entitiesLength += mb_strlen($entity[0]); } else { break; } } } $truncate .= mb_substr($tag[3], 0 , $left + $entitiesLength); break; } else { $truncate .= $tag[3]; $totalLength += $contentLength; } if ($totalLength >= $length) { break; } } } else { if (mb_strlen($text) <= $length) { return $text; } else { $truncate = mb_substr($text, 0, $length - strlen($ending)); } } if (!$exact) { $spacepos = mb_strrpos($truncate, ' '); if (isset($spacepos)) { if ($considerHtml) { $bits = mb_substr($truncate, $spacepos); preg_match_all('/<\/([a-z]+)>/', $bits, $droppedTags, PREG_SET_ORDER); if (!empty($droppedTags)) { foreach ($droppedTags as $closingTag) { if (!in_array($closingTag[1], $openTags)) { array_unshift($openTags, $closingTag[1]); } } } } $truncate = mb_substr($truncate, 0, $spacepos); } } $truncate .= $ending; if ($considerHtml) { foreach ($openTags as $tag) { $truncate .= ''; } } return $truncate; }
CakePHP
truncate($_noticia_html, 10, '...', false, true);
Los parámetros que acepta la función son los siguientes:
// Definimos el texto $_noticia_html = "<p><strong>Sergio Guerrero está cortando este texto</strong></p>"; // Obtenemos un extracto con los 10 primeros caracteres $_extracto_html = truncate($_noticia_html, 10, '...', false, true); // Mostramos el resultado por pantalla echo htmlentities ($_extracto_html); // La salida: // <p><strong>Sergio...</strong></p>
Este ejemplo de uso demuestra como podemos reutilizar fácilmente el código de los Frameworks PHP para mejorar nuestras aplicaciones.
Actualización – 29-01-2010
El repositorio de CakePHP ha sido movido a GitHub: http://github.com/cakephp
Entre las muchas novedades que trae la nueva versión de Internet Explorer (IE 8), hay una que me ha gustado especialmente. Y es que este nuevo IE8 incorpora, de serie, algunas herramientas de ayuda para el desarrollo web. Estas utilidades, que podemos encontrar bajo el menú de Herramientas con el nombre Herramientas de desarrollo, tienen un gran parecido a las utilidades que proporciona la extensión Firebug (extensión recomendable para desarrolladores web y diseñadores) dentro del navegador Firefox. Incorpora también algunas otras características que tendríamos en firefox instalando la extensión Web developers y/o instalando otras como Colorzilla, Firesizer, etc
Este conjunto de herramientas para IE8 permiten:
En la web de msdn podemos encontrar la información oficial sobre estas Herramientas de desarrollo, las cuales continuaré destripando en este blog.

Como ya comenté en mi última entrada del 2008, uno de los objetivos para este año era reducir la lista de libros que tengo pendientes leer y, "gracias" a las dos horas diarias que paso en el tren, he leído: El Origen Perdido, Brooklyn Follies, Sin Noticias de Gurb, El libro negro del emprendedor, Optimización del posicionamiento en buscadores con PHP, y he empezado: Patrones de Diseño de Erich Gamma y PHP Architect, Zend PHP 5 Certification Study Guide.
El libro negro del emprendedor de Fernando Trías de Bes es una lectura que Carlos Blanco recomendó durante su ponencia en el Congreso de Webmasters del 2007 y que también comentó en su blog personal. La recomendación de Carlos Blanco me animó a leer esta obra en la que el autor expone, de una forma muy directa y con un lenguaje sencillo, 14 factores clave del fracaso a la hora de emprender. Fernando Trías de Bes nos ofrece una gran cantidad de reflexiones basadas en su experiencia personal y la de otros 15 o 20 emprendedores a los que tuvo oportunidad de entrevistar y/o conocer.
Al intentar hacer una selección de las frases/reflexiones que me han gustado y aportado, me doy cuenta que debería realizar una reproducción prácticamente completa del libro, pero dejaré aquí 4 de las frases más interesantes:
Os dejo un resumen en PDF del libro, pero os recomiendo que lo compréis y lo leáis completo (sólo cuesta 11€ y se puede leer en poco tiempo).
Para aquellos que quieran estar un poco al día de todo lo que se cuece entorno a este framework PHP, dejo una lista de páginas web donde se pueden encontrar: noticias, ejemplos de código, información sobre las novedades, cambios, libros, etc.