Twig Sugar para Espresso 2 Si desarrollas con un mac y no lo haces con Espresso, debes probarlo. Si no desarrollas con un mac: hazlo :)
Actualmente Espresso es uno de los mejores IDE que puedes encontrar para el completo desarrollo...
Generadores interactivos de Symfony 2 Hace poco me dio por ver el video que tienen en el home de symfony.com. Siempre saltaba directamente a la sección de documentación escrita desde que empecé con la beta 2 o 3. Después de verlo, y probar...
Generadores interactivos de Symfony 2 Hace poco me dio por ver el video que tienen en el home de symfony.com. Siempre saltaba directamente a la sección de documentación escrita desde que empecé con la beta 2 o 3. Después de verlo, y probar...
Crear entidades en Symfony 2 con Doctrine a partir... En Symfony 2 podemos definir los ORM y a partir de ellos generar de forma automática las clases de los modelos y todo el SQL para crear el esquema de la base de datos.
Pero si se quiere hacer a la inversa también...
Si desarrollas con un mac y no lo haces con Espresso, debes probarlo. Si no desarrollas con un mac: hazlo :)
Actualmente Espresso es uno de los mejores IDE que puedes encontrar para el completo desarrollo de una web. Aunque en esto siempre hay opiniones y opiniones. Podría enumerar todas sus características y seguro que me contestais algo así como “bah! pero si eso ya lo hace fulanoid 34.2!”. Pero en su versión 2.0, macRabbit (la empresa desarrolladora) ha decidido incrustarle una de las más prácticas herramientas del mundo: CSSEdit. Por lo tanto, ahora Espresso 2.0 no es solo un completo y ligero editor de código con mil posibilidades, sino que además es el mejor editor de CSS del mercado incluyendo todas las plataformas.
Espresso tiene la posibilidad añadirle plugins, a los que llama Sugars. La verdad es que no he visto muchos Sugars disponibles, pero puedes encontrar algunas joyitas hechas por terceros buscando un poco. Y no son muy difíciles de crear o modificar, son todo XML, así que tienes la opción de cambiarlos a tu gusto.
Eso es lo que he hecho. Encontré un solo Sugar que me ayudara con los documentos Twig. No me terminaba de gustar y también fallaban algunas cosas, así que lo he tuneado cambiando un poco la syntax highlighting y añadiendo algunos snippets.
Escrito el : 01-09-2011 | Por : ZapaN | En : Uncategorized
2
Existe un bundle de Symfony 2 para paginar contenido llamado Pagerfanta ( Symfony2bundles, Github ). En la documentación se describe como se usa. Incorpora una vista por defecto a la que se le pueden pasar algunos parametros para cambiar ciertos aspectos básicos del paginador. Además proporciona una interfaz para crear tus propias vistas.
Bootstrap ( de Twitter ) es un toolkit para facilitar el desarrollo de aplicaciones web sin tener que complicarse demasiado con el estilo. Como se puede ver en la web ofrece un CSS, que además de ayudarnos con la estructura, podremos usar con un montón de componentes. Uno de estos componentes es un típico paginador.
Aprovechando las ventajas que nos dan estos dos prácticos proyectos, he cambiado un poco la vista por defecto de Pagerfanta para que renderice el HTML que renderiza se ajuste al CSS de Bootstrap.
/*
* This file is part of the Pagerfanta package.
*
* (c) Pablo Díez <pablodip@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace ...\Pagerfanta\View;
use Pagerfanta\PagerfantaInterface;
/**
* DefaultInterface.
*
* @author Pablo Díez <pablodip@gmail.com>
*
* @api
*/
class BootstrapView implements \Pagerfanta\View\ViewInterface
{
/**
* {@inheritdoc}
*/
public function render(PagerfantaInterface $pagerfanta, $routeGenerator, array $options = array())
{
$options = array_merge(array(
'proximity' => 3,
'previous_message' => '← Anterior',
'next_message' => 'Siguiente →',
'css_current_class' => 'current',
), $options);
$currentPage = $pagerfanta->getCurrentPage();
$startPage = $currentPage - $options['proximity'];
$endPage = $currentPage + $options['proximity'];
if ($startPage < 1) {
$endPage = min($endPage + (1 - $startPage), $pagerfanta->getNbPages());
$startPage = 1;
}
if ($endPage > $pagerfanta->getNbPages()) {
$startPage = max($startPage - ($endPage - $pagerfanta->getNbPages()), 1);
$endPage = $pagerfanta->getNbPages();
}
$pages = array();
// previous
if ($pagerfanta->hasPreviousPage()) {
$pages[] = array($pagerfanta->getPreviousPage(), $options['previous_message']);
} else {
$pages[] = sprintf('<li class="%s prev"><a href="#">%s</a></li>', 'disabled', $options['previous_message']);
}
// first
if ($startPage > 1) {
$pages[] = array(1, 1);
if (3 == $startPage) {
$pages[] = array(2, 2);
} elseif (2 != $startPage) {
$pages[] = sprintf('<li class="disabled"><a href="#">...</a></li>');
}
}
// pages
for ($page = $startPage; $page <= $endPage; $page++) {
if ($page == $currentPage) {
$pages[] = sprintf('<li class="active"><a href="#">%s</a></li>',$page);
} else {
$pages[] = array($page, $page);
}
}
// last
if ($pagerfanta->getNbPages() > $endPage) {
if ($pagerfanta->getNbPages() > ($endPage + 1)) {
if ($pagerfanta->getNbPages() > ($endPage + 2)) {
$pages[] = sprintf('<li class="disabled"><a href="#">...</a></li>');
} else {
$pages[] = array($endPage + 1, $endPage + 1);
}
}
$pages[] = array($pagerfanta->getNbPages(), $pagerfanta->getNbPages());
}
// next
if ($pagerfanta->hasNextPage()) {
$pages[] = array($pagerfanta->getNextPage(), $options['next_message']);
} else {
$pages[] = sprintf('<li class="disabled"><a href="#">%s</a></li>', $options['next_message']);
}
// process
$pagesHtml = '';
foreach ($pages as $page) {
if (is_string($page)) {
$pagesHtml .= $page;
} else {
$pagesHtml .= '<li><a href="'.$routeGenerator($page[0]).'">'.$page[1].'</a></li>';
}
}
return '<nav class="pagination"><ul>'.$pagesHtml.'</ul></nav>';
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'Bootstrap';
}
}
Buenooo… ya tengo gestor de proyectos listo para ir organizando tareas. He trabajado con Bugzilla, con Mantis y con Jira. Ahora necesitaba algo para mis cosillas personales. Después de buscar opciones, me he decantado por Redmine. La instalación ha sido dura y dolorosa, pero claro, aún estaba con la lenny y eso puede dar problemas con la instalación de algo nuevo (y tanto que los dio…). Opté por hacer un dist-upgrade a squeeze y la cosa fue mucho mejor. Me llevé por delante el Plesk de mi vhost, pero creo que estoy mejor sin él XD
Hace poco me dio por ver el video que tienen en el home de symfony.com. Siempre saltaba directamente a la sección de documentación escrita desde que empecé con la beta 2 o 3. Después de verlo, y probar el generador CRUD en 1 minuto… me quedé con la boca abierta y ojos desorbitados durante el resto del día.
Pegadle un vistazo por que esto puede adelantarte muchísima faena. Es la respuesta a las preguntas que muchas veces hace la gente ¿Por qué un framework? y ¿por qué Symfony?
Como en las jornadas Symfony de este año me sorprendan con técnicas ninja como esta, será el fin de semana más feliz de mi vida XDD
En Flex 3 existe un componente llamado videoDisplay para reproducir videos. Donde trabajo queriamos usarlo para reproducir pelícuas por streaming alojadas en Amazon Cloudfront.
Los enlaces a los videos deben incluir parámetros como fecha de caducidad, firma y una clave para poder reproducirse. Nos encontramos con el problema que no sabiamos como formar la url con esos parametros.
Un mp4 público que no necesitaba de parámetros se veía perfectamente con esta URL:
rtmpe://aaaaaa.cloudfront.net/cfx/st/mp4:dir/file
En cambio si necesitaba firma y demás, pensamos que lo lógico era añadirselos al final:
En Symfony 2 podemos definir los ORM y a partir de ellos generar de forma automática las clases de los modelos y todo el SQL para crear el esquema de la base de datos.
Pero si se quiere hacer a la inversa también se pueden crear los ORM y las clases de los modelos a partir de una base de datos ya creada. Y de forma automática. Eso sí, por favor, que el esquema de la BBDD esté bien creada!
Si seguimos los pasos de configuración de nuestro primer bundle, lo tendremos todo preparado para ejecutar lo siguiente en la consola de symfony y comenzar con la función. Y ese “todo” presupone que añadimos los datos de conexión correctos a una base de datos.
Con los ORM creados Doctrine creará las entidades en un visto y no visto.
Aquí es cuando tu primera vez se te escapa un “jo-der”.
IMPORTANTE: Si tienes más de un servidor php instalado es conveniente indicar la ruta al php.ini adecuado. De no hacerlo puede que los comandos nos devuelvan errores. Usa la opción -c RutaDirectorio. Por ejemplo yo tuve que hacer:
Hace unos días me picó la curiosidad por la segunda versión de Symfony. Había oido hablar de la primera pero no terminaba de convencerme y nunca llegué a reunir ganas para meterme a estudiarlo. Me animé con Symfony 2 después de ver un video de las Jornadas de Symfony de 2010. En la última charla se hacía un avance de lo que aportaba Symfony 2 respecto al 1. Entonces todavía estaba en desarrollo. Hoy disponemos de una versión beta mejorada desde entonces. Después de jugar con ella unos días me da la sensación de estar trabajando sobre un entorno tan sólido como flexible. Usando Symfony 2 tengo desde el principio resueltas tareas con las que seguro te encuentras al desarrollar cualquier proyecto.
Para los que es la primera vez que intentamos hacer algo usando el framework, nos encontraremos perdidos entre ficheros que no tenemos ni idea para que sirven. Recomiendo seguir el tutorial oficial paso a paso para ir encontrando el sentido a su estructura de ficheros y a conceptos que deben quedar claros desde el principio, como el de bundle. Para este artículo me he basado en el caso práctico que han explicado allí y al que se debería pegar un vistazo ( o dos o tres) si no se ha hecho ya.
Lo que voy a hacer en este artículo es indicar los pasos básicos que se suelen seguir para iniciar un proyecto sobre Symfony2. Más que nada, para tener a mano una guía rápida para cuando me olvide :)
Dejando de lado las aplicaciones Flex más básicas, lo habitual es que necesitemos conseguir cierta navegación entre todo el contenido que queremos mostrar.
Hay que tener muy en cuenta que aquí no podemos (o al menos no tendríamos por que hacerlo) ir cambiando de URL. La navegación será totalmente asíncrona desde una misma aplicación y página.
Flex nos proporciona dos estrategias para conseguir ir cambiando el contenido según nuestras necesidades. No sabría muy bien como llamarlas en castellano, así que las nombraré en inglés: navigator containers y view states. Podrían llegar a usarse ambas para cubrir las mismas necesidades, pero lo recomendable es usarlas cada una para unos casos particulares.
Entre las novedades que trae HTML5 hay una API para geolocalización. Para tomar tu posición utiliza la IP del dispositivo desde que cargamos la web. La posición que resulta es aproximada y puede variar muchos metros dependiendo desde donde accedemos y como ajustemos los parametros. Aún así, según el proyecto en el que trabajemos, puede resultar muy útil conocer la zona desde que visitan nuestra web.
Existen dos metodos para recoger las coordenadas de la ubicación del visitante. Uno que sirve para tomar la posición en un momento dado, y otro que va repitiendo la petición, perfecto para el seguimiento de recorridos.
Una de las multiples formas que existen para crear ventanas de dialogo es usar un plugin de jQuery UI.
La documentación oficial está muy detallada y bien estructurada además de incluir numerosos ejemplos.
Se puede crear una función que lance el diálogo con el texto y número de botones que queramos de la siguiente forma:
function showDialog(text, buttons) {
$('#alert-dialog').html(text).dialog({buttons:buttons});
}
var message = "Texto del diálogo";
var buttons = {};
buttons["Cancelar"] = function() { $(this).dialog("close"); };
buttons["Aceptar"] = function() { loquesea(); };
showDialog(message,buttons);
También podemos hacer uso del prototipado de jQuery para hacer la función showDialog genérica y que nos sirva para cualquier elemento que la invoque. Por ejemplo:
jQuery.fn.showDialog = function (text, buttons) {
$(this).html(text).dialog({buttons:buttons});
}
$('#alert-dialog').showDialog(message,buttons);