RSS 2.0 Atom 1.0 CDF  
JASoft.org
El blog de José Manuel Alarcón Aguín. Programación .NET y mucho más...
 

El pasado lunes, en la charla on-line que impartí para el NEt User Group de la UOC sobre Dynamic Data, comenté que existía la posibilidad de sacarle partido a esta interesante tecnología sin tener que crear desde cero un proyecto especial de Dynamic Data, es decir, sin partir de este diálogo:

Tal y como prometí ese día, a continuación explico cómo añadir las capacidades de Dynamic Data a un proyecto Web pre-existente. Como veremos se trata de algo muy sencillo.

Dado que Dynamic Data se basa en el uso plantillas, tanto para las acciones como para generar campos, entidades concretas y otros controles, lo primero que debemos hacer es copiar desde un proyecto Dynamic Data pre-existente los siguientes elementos:

1.- La carpeta de nombre DynamicData
2.- La página maestra Site.master y su correspondiente archivo de código Site.master.vb (o.cs si trabajamos con C#)
3.- La hoja de estilos Site.css

Usa el propio explorador de archivos de Windows para copiarlos, y luego refresca la lista de archivos de proyecto con el botón correspondiente en el explorador de proyectos:

Con esto sólo no es suficiente, ya que también debemos declarar al menos un modelo de datos con el que trabajar.

Asumiendo que hemos definido un contexto de acceso a datos con Linq2SQL o con Entity Framework (enla figura anterior tenemos uno definido en App_Code, con el nombre "MiModelo.dbml"), lo que tenemos que hacer es declararlo en Global.asax a la hora de arrancar la aplicación. Así, debemos escribir en el evento Application_Start un código análogo al siguiente:

    Sub Application_Start(ByVal sender As Object, _
            ByVal e As EventArgs)
        Dim DefaultModel As MetaModel = New MetaModel()
        DefaultModel.RegisterContext(GetType(MiModeloDataContext), _
                New ContextConfiguration() With {.ScaffoldAllTables = True})
    End Sub

Además, debemos asegurarnos de que están incluídos los siguientes espacios de nombres:

<%@ Import Namespace="System.ComponentModel.DataAnnotations" %>
<%@ Import Namespace="System.Web.Routing" %>
<%@ Import Namespace="System.Web.DynamicData" %>

De esta manera, ya tenemos todo lo necesario para poder usar DynamicData junto con controles de acceso a datos en páginas propias. Más sobre esto enseguida.

Antes de continar me gustaría indicar que podemos hacer uso de las rutas de acceso dinámico a acciones con tablas simplemente declarándolas de la manera habitual, es decir, con un código similar al siguiente dentro de Application_Start en Global.asax:

    RouteTable.Routes.Add(New DynamicDataRoute( _ 
        "{table}/{action}.aspx") _
        With {.Constraints = New RouteValueDictionary( _
        New With {Key .Action = "List|Details|Edit|Insert"}), _
        .Model = DefaultModel})

de forma que quedaría un evento con el código de esta figura:

A partir de este momento podríamos manejar cualquier tabla de nuestro modelo de datos con tan sólo escribir una ruta del estilo de esta:

http://miapplicacion/Productos/List

para listar todos los productos de la base de datos y poder editarlos, borrarlos o añadir nuevos. O también:

http://miapplicacion/Clientes/Insert

para insertar un nuevo cliente en la tabla Clientes (si la hubiera). Como vemos muy útil...

Páginas propias con Dynamic Data

Además de lo que acabamos de ver, que genera páginas de mantenimiento con rutas pre-establecidas, podemos sacar partido a Dynamic Data en formularios propios usando controles normales de datos, como una rejilla (GrtidView) o un FormView, usando los controles especiales disponibles a tal efecto:

Por ejemplo, añade una nueva página y en ésta agrega un control DynamicDataManager (figura anterior), y desde el grupo de controles de datos un LinqDataSource o EntityDataSource (según la tecnología que hayas usado para el modelo de datos),  y una rejilla GridView.

En la vista de marcado de la página .aspx edita el control DynamicDataManager para que active esta tecnología en la rejilla, con un código como este:

        <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" >
            <DataControls>
                 <asp:DataControlReference ControlID="GridView1" />
            </DataControls>
        </asp:DynamicDataManager>

Con esto lo que conseguimos es qu el control GridView1 sea capaz de generar automáticamente campos para mostrar y editar campos de la base de datos que se correspondan con el modelo de datos. Es decir, estamos habilitando Dynamic Data en ese control.

En el control LinqDataSource se configura el contexto de datos que representa a nuestro modelo para que utilice una de las tablas que nos interese (por ejemplo la de productos). Asignamos el control DataSource a la rejilla pero deshabilitamos la capacidad de ésta para generar los campos de manera automática.

Ahora sólo nos resta añadir campos dinámicos a la rejilla de forma que, en tiempo de ejecución, éstos se muestren de acuerdo con lo especificado en el modelo de datos (validación, formato, etc... gracias a las DataAnnotations) y en las plantillas para campos, tal y como se hace siempre en Dynamic Data. Para ello existe un nuevo tipo de campo llamado DynamicField que se usa precisamente para esto. Sólo tenemos que indicar el nombre del campo en el modelo que queremos enlazar y listo, ofreciéndosenos ayuda con Intellisense en Visual Studio:

Quedando campos con el siguiente aspecto:

pudiendo asignar otras características como el texto para la cabecera o el formato (si bien este último es más interesante asignarlo mediante metadatos en el modelo, ya que así nos aseguramos un uso consistente en toda la aplicación).

Si no queremos añadirlos a mano Visual Studio nos ofrece un pequeño asistente desde la lista de acciones de la rejilla:

lo que es mucho más cómodo. Podemos añadirle además un DynamicValidator a la página (ver grupo de controles de dynamic data en una figura anterior), asociándolo con el a rejilla. Con esto tenemos controlada la validación de cada uno de los campos dinámicos que editemos dentro de la rejilla.

Ahora, cuando ejecutemos esta página, dentro de la rejilla se mostrarán los campos de acuerdo con el modelo de datos, y tendremos automáticamente los controles de edición más apropiados según el tipo de datos y el modelo, validación de la información introducida, etc... con las ventajas de velocidad y robustez que ello conlleva.

Espero que esto os resulte útil (sobre todo a los que asistísteis el otro día a mi ponencia sobre Dynamic Data, jeje) :-)

Por: José Manuel Alarcon | Friday, March 19, 2010 7:32:21 PM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: ASP.NET


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

La semana pasada estuvimos en OMExpo, la feria de marketing on-line más importante de España, y a todos los que nos visitaron en el Stand les regalamos un ejemplar de nuestro libro "The emailing experience: 49 formas de dar en el blanco". Fué un tremendo éxito y nos agotaron toda la primera edición :-)

El libro recopila 49 consejos para hacer bien marketing a través de correo electrónico: desde cuestiones básicas como qué es y para qué sirve, hasta otras avanzadas como la entregabilidad. Los autores somos María Capón, Pablo Iglesias y José Manuel Alarcón.

Hace unos días sacamos el libro también en formato electrónico para que puedas descargarlo gratuitamente si no tuviste la oportunidad de obtenerlo en papel.

Lo tienes disponible para lectura on-line directamente en Scribd, para descarga en PDF y también para descarga en los principales eBooks del mercado en los formatos .epub y .mobi.

Para descargarlo visita nuestra página de MAILCast.

¡Espero que te guste!

Por: José Manuel Alarcon | Tuesday, March 09, 2010 10:04:01 AM (Hora estándar romance, UTC+01:00)  #    Comments [2] - Trackback
Tags: Eventos


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

El próximo lunes día 15 de marzo de 2010, a las 19:30 hora española, voy a impartir una charla técnica on-line para el DotnetClub de la UOC titulada "Interfaces de datos a la velocidad de la luz: ASP.NET Dynamic Data".

Es gratuita y on-line. Os resumo la charla a continuación:

"Uno de los trabajos más aburridos de los programadores es la creación de interfaces de administración básica de bases de datos. Se trata de los famosos "mantenimientos" que todos nos hemos visto forzados a hacer. Aunque ASP.NET Web Forms nos proporciona fantásticos controles para poder crear interfaces de manera rápida de forma declarativa, ¿no sería fantástico poder automatizar todavía más la creación de estas páginas?. Esto es precisamente lo que nos ofrece ASP.NET Dynamic Data. Con esta tecnología podremos crear interfaces a toda velocidad pero teniendo un control preciso de todo lo que ocurre y pudiendo personalizarlas al máximo."

Si tienes interés en crear interfaces de acceso a datos para la Web a toda velocidad seguro que te interesa.

Anótate en el enlace de arriba.

Además, hoy por la tarde a las 19:30 estaré en Vigo, en la Casa del Libro, hablando de marketing, en concreto de Branding y el libro "En Clave de Marcas". Otro tema completamente diferente, pero si estás por la zona y te interesa pásate por allí.

Por: José Manuel Alarcon | Monday, March 08, 2010 5:39:19 PM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Eventos


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Por si teníamos ya pocas distracciones en este mundillo digital, ahora va Google y nos saca una nueva, y además sin habérselo pedido siquiera: Google Buzz. Se supone que es un mix entre Twitter, Facebook, LinkedIn... y cualquier otra red social que quieras. Te aparece en un lateral de GMail como una carpeta de correo más, pero en realidad es un flujo de información constante de chorradas dichas por cualquiera. Por que esa es otra: es el propio Google el que, según su criterio, te hace "amigo" en Buzz de otra gente, y viceversa. Vale, puedes cambiar tú de amigos si quieres pero ¿quién lo ha hecho?

Hasta hay un chiste con muy mala baba que circula por Internet que dice que Google va a batir todos los records de ingresos en 2010: cobrará 20 dólares a cada usuario de GMail para quitarle Buzz ;-)

A mi me parece una cosa muy poco útil y con Twitter y Facebook ya tengo más que de sobra. Además, esto es como el "double opt-in vs opt-it" en el email: que siempre debería pedirse una doble confirmación para hacer estas cosas y no plantártela por narices. sí, lo sé, te preguntaba si querías activarlo cada vez que entrabas en GMail. Un rollo.

Total, que desactivarlo y deshacerte de él para siempre es muy fácil. Vas a "Ajustes" y dentro de ahí a la pestaña "Buzz":

Una vez ahí puedes escoger simplemente no verlo, o bien pulsar el enlace rojo y desactivarlo para siempre. Al hacerlo te sale esta ventana de advertencia:

No te dejes amilanar por él: no te afectará para nada a tu cuenta de GMail, Google reader o cualquier otro servicio de Google que uses, así que no te cortes y dile que sí ;-)

 

Por: José Manuel Alarcon | Tuesday, February 23, 2010 10:34:18 AM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Mundo TIC


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

He de confesarlo: me encanta el iPhone de Apple. A la espera del nuevo Windows Phone 7, del que tengo muchas dudas y hasta que lo vea en la mano y sepa que hay muchas y buenas aplicaciones, mi favorito sin duda sigue siendo el iPhone 3Gs. Intenté volver a un HTC Touch hace unos meses cuando me cargué el anterior iPhone y no lo soporté ni un día. Sólo de pensar en volver al stylus me dan escalofríos. Una de las cosas que más me gusta es el navegador Safari que lleva embebido. Ahora empieza a ser algo más normal que los navegadores móviles visualicen las páginas Web como en un navegador de escritorio, pero no era así ni mucho menos hasta que apareció el iPhone 2G (el primero que tuve) hace ya 3 años. Este teléfono de hecho fue el que sirvió de revulsivo para que el mercado de los Smartphone haya explotado, y ahora todos siguen la estela a ver si lo imitan. En eso, he de reconocerlo, Windows Phone 7 (al contrario del 6.5), parece que va a ser innovador escapando de las pantallitas de iconos propias del "ayfon".

El caso es que cada vez más gente navega desde el móvil y además, según Market Share, el informe de diciembre de 2009 de Admob, el iPhone arrasa entre los dispositivos móviles a la hora de navegar por Internet, sobre todo en Europa y Oceanía:

por lo que es importante ser lo más amigable posible con estos chismes. Dado que la página se visualiza perfectamente al tener tanto este aparato como los móviles con Android o -últimamente muchos otros incluyendo Windows Mobile- Opera Mobile, una cosa que podemos hacer es facilitar que los visitantes nos coloquen como favoritos.

Cuando navegas a una página con Safari para iPhone, al pulsar el botón "+" de la parte de abajo te salen estas opciones:

la segunda de ellas te permite añadir la página como un acceso directo desde el "escritorio" del teléfono, como un programa más de los disponibles, lo cual es muy útil si accedes a menudo. Por defecto el aparato hace una captura de pantalla de la página y la usa como icono a la hora de añadirlo:

¿Ves algo en el icono anterior? Yo tampoco. Está bien el intento pero no suele servir de mucho, al menos en los blogs y similares. Tal vez en las páginas corporativas que tengan algo destacado que se vea en la mini-captura.

Lo ideal sería que tuviésemos nosotros control sobre el icono que se utiliza. Para ello hay una forma muy sencilla: crear un gráfico en formato PNG de tamaño 60x60 pixeles, y colocarlo en la raíz de nuestro sitio web con el nombre especial: "apple-touch-icon.png".

Con esto, ahora, a la hora de añadir el acceso directo obtenemos el icono adornado por el iPhone con un bonito efecto de reflejo 3D y también bordes redondeados:

Para que te hagas una idea de la diferencia, el icono original es este:

Y así es como queda una vez colocado en el escritorio del teléfono para un fácil acceso directo (abajo a la derecha):

Mola ¿eh?

Si el gráfico se llama "apple-touch-icon-precomposed.png" en lugar del nombre anterior, el teléfono no le añadirá ninguno de estos efectos dejándolo como está.

Si no puedes copiar el icono en el raiz de tu web o si quieres darle un nombre diferente puedes usar una cabecera META en tu página Web para indicar qué icono quieres usar, así:

<link rel="apple-touch-icon" href="mi_icono.png"/>

De manera similar, si se trata de una aplicación, puedes especificar la imagen que quieres que el iPhone muestre mientras se inicia y se conecta (algo asícomo una Splash Screen para el chisme) usando una cabecera parecida:

<link rel="apple-touch-startup-image" href="splash.png">

La imagen tiene que ser de 320x460 píxeles de tamaño. Si no la especificas usará la captura de pantalla de cómo estaba la última vez que la usaste.

<meta name="apple-mobile-web-app-capable" content="yes" />

Si quieres que además la aplicación se muestre a pantalla completa (sin los elementos propios del navegador) añade esto:

<meta name="apple-mobile-web-app-capable" content="yes" />

Espero que te sea útil si vas a hacer algo para este teléfono.

Por: José Manuel Alarcon | Saturday, February 20, 2010 1:17:17 PM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Desarrollo Web


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

El próximo miércoles día 24 a las 18:30 de la tarde, estaré en la Universidad Autónoma de Madrid hablando con los estudiantes de informática acerca de muchas cosas interesantes de la vida tecnológica :-)

Esta charla/encuentro coincide con el OMExpo (antiguo Online Marketing España) y con Expo e-learning, por lo que habrá mucha gente por la zona.

Si estás cerca, ¡Apùntate!

Ah!, y por cierto, si vas a estar en OMExpo, pásate por nuestro stand (el 92) y sólo por hacerlo te regalaremos nuestro último libro lleno de consejos prácticos para desarrollar campañas de email marketing exitosas. Toda la info aquí.

Por: José Manuel Alarcon | Wednesday, February 17, 2010 10:37:04 AM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Eventos


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Hoy en día si no apareces en las primeras posiciones en los resultados de las principales búsquedas relacionadas con tu actividad, es como si no existieras. Si analizas los logs del servidor puedes comprobar que un altísimo porcentaje del tráfico que entra en tu Web es directamente procedente de buscadores. En España, además, el cuasi-monopolio en esto lo tiene Google, por lo que casi se puede afirmar que si no apareces en Google no existes. Hay gente que no se da cuenta del verdadero poder que tienen estas herramientas de búsqueda y lo que podrían hacer si decidieran sesgar un poco sus resultados.

En los últimos años se ha desarrollado ampliamente el concepto y las técnicas de SEO: Search Engine Optimization, u Optimización para Motores de Búsqueda. Existen técnicas SEO lícitas y por lo tanto aprobadas por los buscadores, y también técnicas ilícitas que pueden funcionar una temporada pero que cuand te pille el buscador te penalizará tanto que tu web se verá relegada al olvido. Aparte de estas técnicas más o menos elaboradas, hay muchas otras cuestiones que nuestro código HTML y la estructura de la página pueden cumplir para mejorar la consideración que de la misma tienen Google, Bing, Yahoo! y compañía. Por ello es muy importante que nuestro código HTML generado cumpla con multitud de normas, que no haya enlaces rotos, que tengamos un archivo sitemap.xml, etc... Son multitud de factores los que debemos tener en cuenta, y si aunque seamos expertos SEO puede ser una tarea imposible tener todo controlado.

Para ayudarnos con esto Microsoft ha sacado una excelente herramienta gratuita llamada SEO Toolkit. En este artículo vamos a analizarla y explicar sus funcionalidades para que puedas sacarle partido enseguida y mejores el posicionamiento de tus Webs.

Antes de nada quiero dejar claro que esta herramienta, aún siendo de Microsoft y con una interfaz bastante liosa de poner a andar, funcionará con cualquier web creada con cualquier lenguaje y en cualquier sistema.

Instalación y puesta en marcha

Instalar el SEO Toolkit es un tanto lioso. Para ello debemos descargarnos antes la herramienta Microsoft Web Platform, que nos permite gestionar desde su interfaz infinidad de herramientas de desarrollo Web y proyectos Open Source. Te descargas el ejecutable e instalas el Microsoft Web Platform. Tendrás que bucarlos en tu menú de inicio y lanzarlo. Esta herramienta te presenta listas de herramientas clasificadas en categorías, las cuales puedes elegir e instalar según tus necesidades. En mi opinión, esta herramienta es un tostón y prefiriría una buena Web con las mismas herramientas clasificadas, pudiendo descargar individualmente cada una de ellas según la necesite. Pero Microsoft tendrá sus razones para haberlo hecho así.

En este caso, para localizar el SEO Toolkit en la herramienta y poder instalarlo, tenemos que ir a la pestaña de "Web Platform", sección "Web Server" y elegir su personalización:

Al hacerlo se nos muestra una lista de herramientas entre las que tenemos la que estamos buscando:

OJO: el SEO Toolkit no es una herramienta individual, sino que trabaja desde dentro de la interfaz de gestión de IIS 7.0 o superior, por lo que tendremos que tener instalado este servidor Web en nuestro equipo antes de poder ponerlo en marcha.

En mi opinión esto es una gran lástima pues a Microsoft le hubiera sido incluso más fácil hacer del SEO Toolkit un programa independiente y no hacerlo depender de IIS, teniendo en cuenta además que funciona con cualquier Web remota o local, de IIS, de Apache o cualquier otro servidor, y no sólo con IIS. Pero bueno, dado que es gratuita habrán pensado que así al menos te hacen ver su propio servidor un poco. En cualquier caso todos los males sean esos :-)

Pulsa "instalar" en la ventana de la figura anterior y ¡Listo!. Eso sí, es un poco desconcertante, ya que cuando termina la instalación, no tenemos mensaje de aviso alguno ni tampoco encontraremos un acceso directo a la herramienta en nuestro menú de inicio. Para utilizarla tendremos que abrir la herramienta de gestión de IIS y localizarlo en la página de gestión del servidor o de cualquiera de las Webs que tengamos definidas:


Pulsa para aumentar

Funcionalidad de la herramienta

Cuando hacemos doble-clic sobre el icono se abre la herramienta, que nos brinda tres opciones:

· Análisis de sitios: Permite analizar sitios existentes y generar completísimos informes orientados al SEO, así como lanzar consultas sobre esos resultados, exportarlos, compararlos, etc... Es en lo que nos vamos a centrar en este artículo.

· Sitemaps: ayuda a generar y gestionar archivos Sitemap para nuestra Web, de forma que ayudemos a los buscadores (especialmente Google) a indexarlos adecuadamente.

· Robots: el archivo robots.txt de una web define qué partes de la misma deben a evitar los robots de búsqueda (o arañas) de los buscadores. Esta característica nos ayuda a crear este tipo de archivos.

Análisis de sitios con SEO Toolkit

Si creamos un nuevo análisis nos aparecerá una ventana en la que se nos pide que ajustemos unos parámetros básicos a partir de los cuales el software empezará a actuar:

Lo único que es necedsario introducir es un nombre para el análisis así como la URL de la que queremos partir para comenzar el análisis (en este caso he usado nuestra página de www.campusmvp.com). En los ajustes avanzados podemos decidir el máximod de recursos a descargar, el tamaño máximo a descargar de un determinado archivo (para evitar descargar archivos pesados innecesariamente), si seguimos o no los enlaces que están marcados con el atributo "nofollow", y si debemos hacer caso omiso o no de la etiqueta meta "noindex". Mirecomendación sería marcar estas dos últimas casillas, pues es cómo se comportará la araña de Google. 

La lista desplegable de enlaces externos sirve para decidir qué tipo de URL vamos a considerar como tales, es decir, cuáles están fuera de la web actual y cuáles no.

Es posible establecer usuario y clave para que el sistema funcione con sitios web no públicos, protegidos con credenciales de acceso.

Una vez que pulsamos el botón de "OK" se lanza un proceso que tardará más o menos en función del tamaño de la web analizada y que, a todos los efectos, simula el proceso que llevaría a cabo la araña de un buscador cuando está indexando el sitio web en cuestión. Nuestro particular robot de búsqueda analiza todo lo que va descargando y lo compara contra una base de datos de normas SEO para generar finalmente un informe.

Lo primero que vemos al terminar es el resumen del análisis:

No te agobies si te salen muchas violaciones de buenas prácticas SEO. Es de lo más normal. Es casi imposible que no se te escape algo, y muchas cosas, si bien son recomendables, no son imprescindibles ni mucho menos. Otras sí ;-)

Como vemos en la figura anterior se nos muestra un resumen de todas las buenas prácticas que estamos incumpliendo, y cuántas veces. Si hacemos doble-clic sobre cualquiera de los elementos de esa lista se abre una ventana de detalle, que nos indicará muchísima información sobre cada violación: en qué lugar se produce, por qué es importante, cómo está formado el código, qué podemos hacer para solucionarlo, etc...

Encontrarás la mayoría de las normas de lo más útil, así que repásalas con calma.

En los otros apartados del lateral puededs profundizar en otra información relacionada. El primero, "Violations", tenemos la lista completa de problemas detectados que veíamos de manera resumida en la figura anterior.

El apartado "Content" se nos muestran los contenidos del sitio Web agrupados por tipos de archivo, carpetas, y otros criterios. Nos sirve para darnos cuenta de cómo está organizado el sitio.

El apartado "Performance" se nos muestra una visión del rendimiento de descarga de la Web en el momento en que fue capturada. Así podemos ver los tiempos y tamaños de descarga y nos puede ayudar a indetificar páginas con problemas, o archivos muy pesados que pueden interferir en el buen trabajo de la aplicación o sitio. La herramienta ya nos apunta de entrada los archivos problemáticos or que se descargan lentamente. Podemos ver la información por carpetas, tipos de archivo, páginas demasiado saturadas de elementos.

Finalmente el apartado "Links" es muy interesante porque nada como los enlaces influye más en el posicionamiento de las páginas. Así podemos ver las relaciones existentes entre nuestras páginas, cuáles son las más enlazadas, la profundidad de los enlaces, las redirecciones (las arñas no suelen pasar de la segunda redirección, por lo que tienen especial importancia), lo enlaces rotos (también importantísimos), etc...

Consultas

Todos estos apartados nos ayudarán a solucionar multitud de fallos y a mejorar el código del sitio Web de forma que se posicione mejor ante los ojos de los todo poderosos buscadores. No obstante para empezar a veces puede resultar difícil si tenemos muchas cosas a las que atender. Qué duda cabe que la vista por defecto, la de resumen, nos ayudará mucho, pero si queremos profundizar o si necesitamos localizar recursos concretos las herramientas de consulta integradas en SEO Toolkit nos van a resultar de gran ayuda.

Dentro del menú desplegable de laparte superior tenemos el apartado "Query", que nos permite crear nuevas consultas de los recursos descargados por nuestra araña y también de las reglas que se han transgredido en el sitio. Así, podremos elegir uno entre múltiples campos de filtrado (dependiendo del tipo de consulta que hagamos), el tipo de comparación a realizar, y el parámetroa comparar, combinando varias condiciones simultáneamente:

Por ejemplo, si tenemos un enlace roto y queremos averiguar todas las páginas apuntan a éste, podemos hacer una consulta gráfica como esta:

Es posible agrupar los resultados. Tenemos la posibilidad de exportar los resultados de la consulta o guardarla para su reutilización posterior. Como vemos de lo más útil.

Exportar

Todos los resultados de la actividad de la araña y el correspondiente informe total es posible exportarlo a formato CSV (archivo de texto con valores separados por comas), para abrirlocómodamente en Excel y poder procesar por nosotros mismos los resultados, generar informes para clientes, filtrar con las características de Excel, etc... Algo que personalmente encuentro muy útil.

Comparar

Dado que la herramienta nos dará muchas indicaciones y que seguramente vamos a hacerle caso a muchas de ellas, cambiando la Web, resulta de especial interés la herramienta de comparación que trae:

De esta forma, tras haber aplicado los consejos SEO obtenidos por el análisis anterior, podemos pasar de nuevo la araña sobre la misma web y generar otro nuevo informe. Si los comparamos obtendremos un análisis de las mejoras introducidas que nos servirá para darnos cuenta de la influencia de las medidas introducidas.

En resumen

El SEO Toolkit es una herramienta gratuita de Microsoft que nos ayudará a mejorar mucho la posición de nuestra web en los buscadores, ahorrándonos muchas horas de estudio propias de un SEO. A pesar de su dificultad para ponerla en marcha para los no técnicos (necesitarás IIS 7.0 o superior) merece la pena instalar y pasar su araña a nuestros sitios para que los analice.

Aunque nunca va a sustituir los servicios de un buen SEO y además la posición en los resultados de búsqeuda no dependen únicamente (ni mucho menos) de la calidad de nuestro código sino que es más un factor relacionado con la relevancia de nuestro sitio, desde luego nos ayudará a partir de una buena base, y puede sustituir (y mejorar) a la mayoría de los SEO aficionados que nos vamos a encontrar por ahí: desconfía de las empresas o "expertos" que tanto te optimizan la página para SEO, como te diseñan la Web, te la programan y te dan el hosting si se tercia ;-)

¡Espero que te resulte útil!

Por: José Manuel Alarcon | Sunday, February 14, 2010 7:23:28 PM (Hora estándar romance, UTC+01:00)  #    Comments [1] - Trackback
Tags: Herramientas


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

.NET 4.0 dispone de soporte para tiempo de ejecución de lenguajes dinámicos, el DLR (Dynamic Language Runtime). El propósito del DLR es permitir que los lenguajes de tipo dinámico -como PHP, JavaScript, Ruby, Python, Lisp o Groovy, por citar unos cuantos- puedan ejecutarse en la plataforma y además interactuar con código escrito en un lenguaje .NET -como C# o VB.

El DLR introduce en el framework una serie de clases dinámicas de comportamiento dinámico que ayudan mucho a la hora de interactuar con estos lenguajes o acceder a COM, pero que abren la puerta a crear monstruos de código si son mal utilizados. De hecho gurús de la plataforma como mi buen amigo Octavio Hernández, reniegan de esta característica ;-)

Lo cierto es que en general yo no recomendaría el uso de las clases dinámicas, pero sí que pueden llegar a ser útiles en algunas ocasiones. Por ello en este artículo voy a presentar la más útil y fácil de usar de todas, la clase ExpandoObject.

Añadiendo miembros dinámicamente

Este objeto es, en realidad, una colección genérica bien disfrazada con "azucar sintáctico" de manera que en lugar de andar escribiendo .Add y .Remove con el nombre de los miembros, se pueden escribir directamente en el código y el compilador hace caso omiso de ellos, posponiendo la comprobación de su existencia al tiempo de ejecución. Lo entenderemos mejor con un ejemplo:

//Creo el objeto
dynamic Persona1 = new System.Dynamic.ExpandoObject();
//le añado algunas propiedades
Persona1.Nombre = "JM";
Persona1.Apellidos = "Alarcón aguín";
Persona1.Edad = 37;

Fijémonos en lo que hemos hecho aquí: primero hemos declarado una nueva clase de tipo ExpandoObject, la cual está en el espacio de nombres System.Dynamic. Si hubiésemos escrito simplemente el nombre de la clase VS2010 nos da ya la opción de añadir el "using" correspondiente en la parte de arriba del código:

Hay que fijarse también en una cosa importante: en C# debemos declarar el tipo de la variable que va a contener el objeto como dynamic. Fíjate en que lo lleva delante. Este nuevo tipo de C# se puede considerar que es casi idéntico al tipo Object, pero su principal diferencia es que cuando declaramos una variable con dynamic, el compilador se salta la comprobación estática de tipos durante la compilación. De esta forma el compilador no "rompe" cuando compilamos si intentamos utilizar una propiedad o método de la clase dinámica aunque éstos no existan. En VB no es necesario un tipo especial porque este lenguaje soporta el enlazado de tipos postergado.

Bien, una vez creado el objeto dinámico podemos empezar a añadirle propiedades con sólo escribirlas, como se ve en las líneas anteriores, tras la declaración. Así, al nuevo objeto le añadimos una propiedad Nombre, otra Apellidos y otra Edad simplemente poniendo un punto y escribiéndola. Es decir, como si ya existiera de antemano, cosa que no es así. En la práctica lo que conseguimos es que si la propiedad existe que se asigne, pero si no existe se crea dinnámicamente y se asigna, es decir se van creando propiedades sobre la marcha.

Si ahora escribo:

Console.WriteLine("Persona: {0} {1}, Edad: {2}", Persona1.Nombre, Persona1.Apellidos, Persona1.Edad);

Obtendré por pantalla sin problemas el nombre y apellidos, seguidos de la edad anotadas en este nuevo objeto dinámico.

Los tipos apropiados para las propiedades se infieren del valor que se le pasa al asignarla. Así en el ejemplo, para el nombre y apellidos tendremos tipos string, y un int para le Edad. Además el tipo cambia también dinámicamente. Por ejemplo si asigno el valor 37 a la propiedad Edad su tipo será un Int. Sin embargo si acto seguido le asigno, por ejemplo, 10E10 (un número muy grande), automáticamente la propiedad cambia y ahora es de tipo double. Exactamente igual que pasaría en JavaScript u otro lenguaje dinámico tradicional.

Podemos crear propiedades de objetos dinámicos que a su vez son también objetos dinámicos. Por ejemplo:

Persona1.Domicilio = new ExpandoObject();
Persona1.Domicilio.Ciudad = "Vigo";

De este modo acabo de crear una propiedad Domicilio que es dinámica y le he creado a su vez una propiedad Ciudad. Así puede escribir Persona1.Domicilio.Ciudad para obtener el valor "Vigo".

Estos tipos dinámicos, aunque están soportados por el entorno de Visual Studio 2010, no nos ofrecen (al menos en la Beta2) soporte para Intellisense, en el sentido de que una vez definida la propiedad, esta no aparece en la ayuda contextual cuando volvemos a usar el objeto y ponemos un punto:

Como vemos, nos indica que lo que escribamos a continuación del punto será interpretado en tiempo de ejecución, no al compilar, y por tanto no nos muestra ayuda al respecto.

Con esto es muy facil, por ejemplo, crear un nuevo objeto dinámico dinámicamente (valga la redundancia) a partir de datos contenidos en algún lado. El ejemplo típico es cargar un archivo XML e ir recorriendo sus nodos e ir asignando a su vez propiedades alobjeto dinámico. Así podremos acceder más fácilmente a los datos desde el código pudiendo escribir notaciónn común de objetos (nombres y puntos) para acceder a ellas en lugar de estar escribiendo sintaxisd más complejas para leer valores de nodos o atributos XML. También nos valdría de modo similar para interpretar JSON.

Una aplicación especialmente interesante es a la hora de definir vistas de ASP.NET MVC 2.0 de manera dinámica, como explica Phil Haack en este post (inglés).

Además de propiedades es posible definir también métodos dinámicamente, si bien éstos son de menor utilidad ya que deberán ser estáticos y por lo tanto no pueden acceder al resto de propiedades del objeto.

Por ejemplo:

Persona1.Saludar = new Func<STRING, bool>((sSaludo) =>
{
    Console.WriteLine(sSaludo);
    return true;
});

Con esto creamos un nuevo método Saludar, y podemos escribir: Persona1.Saludar("Hola") para obtener ese mensaje por pantalla en este caso simple. El método se crea con una expresión Lambda por lo que siempre deve devolver algo. En este caso como no nos interesa para nada el valor devuelto he optado por devolver un booleano sin más. Ya digo que no tienen demasiada utilidad.

Si llamamos a la función sin pasarle el número de parámetros apropiado no se nos quejará el compilador y podremos generar el ejecutale. Sin embargo a la hora de ejecutar la aplicación romperá miserablemente:

Enumeración y eliminación de miembros

Hasta ahora hemos visto lo fácil que es crear un miembro, pero claro, nos será útil solamente si sabemos de antemano qué miembros están disponibles. ¿Cómo podemos averiguarlo?. Esto puede ser útil para, en el caso de crearlo a partir de un origen de datos arbitrario, poder enumerarlos y comprobar que existen un mínimo determinado de ellos, o simplemente para poder hacer introspección de los objetos. Siempre podríamos usar reflexión pero sin embargo no habríamos ganado demasiado ¿verdad?.

Fijémonos en la definición de la clase ExpandoObject (en C#):

public sealed class ExpandoObject : IDynamicMetaObjectProvider, 
    IDictionary<string, Object>, 
    ICollection<KeyValuePair<string, Object>>, 
    IEnumerable<KeyValuePair<string, Object>>, 
    IEnumerable, INotifyPropertyChanged

Como vemos implementa una interfaz IDictionary genérica y también una ICollection e IEnumerable. Es decir, en el fondo se trata ni más ni menos de una colección genérica capaz de albergar cualquier cosa. Los miembros que vamos añadiendo se incorporan a una colección interna. Por lo tanto para poder enumerarlos sólo hay que hacer uso del objeto como una colección o un diccionario:

IDictionary<String, Object> miembros = (IDictionary<string, Object>)Persona1;
foreach (System.Collections.Generic.KeyValuePair<String, Object> miembro in miembros)
{
    Console.WriteLine("{0}: {1}", miembro.Key, miembro.Value);
}

O de manera más directa y entendible:

foreach(var miembro in (IDictionary<string, Object>)Persona1)
{
    Console.WriteLine("{0}: {1}", miembro.Key, miembro.Value);
}

Como vemos simplemente hacemos un "cast" a la interfaz IDictionary y a partir de ese momento lo manejamos como cualquier otra colección de objetos cuya clave es de tipo texto. Gracias ello podemos añadir nuevos miembros usando el método Add del diccionario, pero, lo más importante, podemos eliminarlos usando el método Remove, por ejemplo:

((IDictionary)Persona1).Remove("Nombre");

En la que me he cargado la propiedad Nombre.

Detectando cambios en propiedades

Si nos fijamos en la definición de la clase vemos que implementa una interfaz INotifyPropertyChanged. Ésta define un evento llamado PropertyChanged que nos sirve para detectar el momento en que cambia una propiedad o se asigna por primera vez. Así, podemosdefinir una función como esta:

private static void DetectarCambios(object sender, PropertyChangedEventArgs e)
{
    Console.WriteLine("Se ha asignado la propiedad '{0}'", e.PropertyName);
}

y detectar los cambios en miembros simplemente estableciendo esa propiedad de la interfaz, así:

((INotifyPropertyChanged)Persona1).PropertyChanged += new PropertyChangedEventHandler(DetectarCambios);

No acaba de ser del todo útil porque no nos deja averiguar qué valor se ha asignado (aunque es fácil de determinar usando la colección interna como acabamos de ver hace un momento, pero puede ayudarnos en algunos casos. No obstante si queremos crear objetos dinámicos y tener control absoluto sobre cómo se crean sus miembros en lugar de ExpandoObject deberíamos usar la clase DynamicObject.

Colecciones de objetos dinámicos

Para terminar con este interesante tema me gustaría comentar cómo se crean colecciones de objetos dinámicos. Consideremos el siguiente código:

dynamic vecinitos = new List<dynamic>();

vecinitos.Add(new ExpandoObject());
vecinitos[0].Nombre = "Homer";
vecinitos[0].Apellidos = "Simpson";
vecinitos[0].Ropa = "Camisa blanca, pantalones azules";

//No son objetos iguales
vecinitos.Add(new ExpandoObject());
vecinitos[1].Nombre = "Ned";
vecinitos[1].Apellidos = "Flanders";

foreach (var vecinito in vecinitos)
{
    Console.WriteLine("{0} {1}", vecinito.Nombre, vecinito.Apellidos);
}

Vemos que la lista genérica se crea del tipo dynamic, y no del tipo ExpandoObject. Esto es normal ya que de esta forma estamos acogiendo objetos dinámicos de cualquier tipo y no sólo de esta clase particular. Aunque en este ejemplo concreto funcionaría perfectamente haberla definido con ExpandoObject, en general usaremos dynamic (u Object en VB) porque así nos aseguramos que vengan de donde vengan los objetos de la lista ésta funcionará sin problema.

A continuación definimos cada elemento añadido la lista de forma que creamos dinámicamente sus propiedades. Finalmente los recorremos en un bucle para mostrar sus propiedades.

Si en el bucle hubiésemos usado esta línea de código en ugar de la anterior:

Console.WriteLine("{0} {1}", vecinito.Nombre, vecinito.Apellidos, vecinito.Ropa);

Lo que hubiera pasado es que la primera vuelta (la de Homer) hubiera funcionado bien, pero como en el segundo elemento (Flanders) no hemos definido la propiedad ropa hubiésemos obtenido un error en tiempo de ejecución. Con esto quiero dejar claro que aunque se defina una propiedad para uno de los objetos, ésta no queda definida en los demás, ya que son objetos absolutamente independientes, así que hay que tener cuidado y no dar por hecho que una determinada propiedad va a existir para un objeto dinámico concreto.

En resumen

Los objetos dinámicos creados a partir de la clase ExpandoObject están pensados para trabajar con lenguajes dinámicos desde C# y VB. Ello además nos proporciona una nueva herramienta que podemos usar en otro tipo de desarrollos aunque no estén relacionados con los lenguajes dinámicos. Eso sí: debemos usarlos con sumo cuidado y sólo en situaciones que estén muy justificadas, porque de otra manera correremos el riesgo cierto de cometer muchos errores difíciles de detectar. De hecho una de las ventanas de los lenguajes tipados frente a los dinámicos es que es mucho más difícil meter la pata porque debes tener claro todo el rato qué tipo de información estás manejando. Así que ¡cuidado!.

Los objetos ExpandoObject son en realidad una forma fácil de acceder colecciones genéricas, por lo que debemos tener con ellos el mismo cuidado que con las colecciones. Así que cuando escribamos una propiedad con la notación del punto debes recordar que por debajo lo único que estás haciendo es añadir un elemento a una colección. Tenlo en mente todo el rato.

He dejado todo el código de este artículo en un ZIP para que puedas descargarlo y haer tus propios experimentos con estos objetos dinámicos y ver cómo se comportan.

¡Espero que te resulte útil!

Por: José Manuel Alarcon | Saturday, February 06, 2010 8:57:14 PM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Programación | Visual Studio


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Si has utilizado en producción Windows azure, y en concreto su almacenamiento local para tablas, blobx y colas (Windows Azure Storage), habrás observado que cuando defines una cuenta de almacenamiento dispones de dos claves de seguridad para acceder a las mismas, una primaria y otra secundaria:

¿Por qué hay dos claves, para qué sirven y cómo se relacionan?

La verdad es que es un sistema interesante. Ambas claves son equivalentes y ambas sirven para acceder a la cuenta de almacenamiento, así que podemos utilizar una u otra indistintamente. Generalmente usaremos la primera y la desplegaremos en nuestra aplicación Azure, dentro de sus propiedades de configuración.

Al tener dos claves lo que conseguimos es que no exista ni un segundo de parada de nuestra aplicación si necesitamos cambiarla.

Supongamos que estamos usando la primera clave y alguien nos la roba y tiene acceso también al almacenamiento. ¿Cómo procederíamos para cambiarla y no parar el servicio?

El procedimiento sería el siguiente:

1.- Cambiamos el archivo de configuración de la aplicación Azure para que pasemos a utilizar la segunda de las claves. Este cambio es instantáneo y no es necesario desplegar de nuevo la aplicación. A partir de este momento se está usando la segunda clave y la primera no nos hace falta.

2.- Vamos a la pantalla anterior y pulsamos el botón de regenerar la primera clave. A partir de ese mismo instante la clave anterior queda invalidada y el que nos la haya robado no podrá utilizarla.

3.- Opcionalmente, volvemos a cambiar la configuración para usar la nueva clave primera, aunque no es necesario y podemos quedarnos con la segunda el tiempo que necesitemos, haciendo el procedimiento en sentido inverso si se viese comprometida.

Como vemos este pequeño truco es realmente útil para no interrumpir en ningún momento el funcionamiento de la aplicación Azure, cosa que sí tendríamos que hacer en caso de que sólo existiera una clave.

Espero que lo encuentres útil :-)

Por: José Manuel Alarcon | Thursday, January 28, 2010 9:37:10 PM (Hora estándar romance, UTC+01:00)  #    Comments [0] - Trackback
Tags: Azure


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner

Una situación muy común en las empresas cuando les hablas de formación se produce cuando los responsables de RRHH/Equipos/Proyectos te dicen que no forman a su gente porque si lo hacen luego éstos se les marchan a la competencia. Pasa constantemente.

Es cierto que la formación mejora la empleabilidad de la gente. De eso no hay duda. Pero el que se vayan o se queden depende fundamentalmente de que la empresa ponga los medios y -sobre todo- las condiciones para "fidelizar" al empleado, y que por lo tanto éste desee permanecer en ella, porque está motivado, tiene posibilidades de mejorar y sobre todo se sienta realizado en el plano laboral.

Si un trabajador se marcha tras la formación es que ya deseaba irse antes de la formación. Es decir, no existe una relación de causalidad entre formar a una persona y que se quiera marchar de la empresa, como es obvio. Es más, el hecho de que la empresa no les brinde la oportunidad de formarse es una razón más para querer abandonarla, pues no se apuesta por esa persona. Claro que la persona también tiene que ser de una determinada forma, y es este tipo de trabajador al que se debiera apoyar.

En la actual sociedad competitiva y globalizada, donde las barreras de entrada a muchos negocios y actividades se han reducido o, directamente, han desaparecido, las empresas deben saber responder con celeridad a los cambios. Es más, deben en realidad tratar de adelantarse a los cambios y tendencias. En el ámbito tecnológico en el que nos movemos la audiencia de mi blog y yo, la única constante es el cambio.

La verdadera formación continua no sólo se trata del aprendizaje de una determinada disciplina técnica o competencia, sino que implica también "vivir en el mundo", comprender lo que te rodea, estar al tanto de los cambios y tendencias importantes que influyen o influirán a tu trabajo. Sólo de este modo podrán los trabajadores ayudar a su empresa a mejorar, a anticiparse, a ser diferente.

Obviamente esto implica no sólo que la empresa brinde la oportunidad de hacerlo, sino también trabajadores que tengan interés por ello. Estas personas son algo más que trabajadores, son profesionales.

Lo que expongo se aplica a cualquier trabajo que implique la realización de tareas que no sean mecánicas. En el caso de trabajadores de "cuello blanco" -los que se han dado en llamar "trabajadores del conocimiento"- son la práctica totalidad de los puestos.

En el caso concreto de los técnicos TIC esto último es especialmente cierto. El que se haya metido a programador, administrador de sistemas, etc.. pensando en que no se va a formar hasta el fin de sus días está muy equivocado. Sorprende entrevistar a recien titulados en informática que creen que por haber estudiado esta carrera ya saben todo lo que necesitan. También existe otra categoría de informáticos, muy común, cuya única formación es buscar en Internet la solución concreta al problema concreto que tienen en cada momento, pero sin ir más allá. ¿Cuántos programadores conoces que dicen que al terminar su jornada laboral no quieren tocar un ordenador?.

No son precisamente estos últimos aquellos que las empresas deben cuidar y apostar por su formación.

Pienso que las empresas, más que preocuparse porque si forman a los trabajadores éstos se les van a marchar, deberían preocuparse porque si no los forman, a lo mejor, se les quedan. Y esto sí que será un problema a largo plazo ;-)

En fin, esta es mi reflexión personal para una tarde domingo lluviosa, sin nada mejor que hacer, y espero que se me haya entendido :-)

Por: José Manuel Alarcon | Sunday, January 17, 2010 7:20:06 PM (Hora estándar romance, UTC+01:00)  #    Comments [8] - Trackback
Tags: Mundo TIC


Sígueme en:

:: Twitter JM Alarcón: tecnología, marketing, este blog y frikadas varias
:: Twitter campusMVP: los mejores recursos sobre tecnología Microsoft: trucos, artículos, noticias, vídeos...
:: Facebook campusMVP: los mismos mejores recursos pero en directamente en Facebook.
:: Boletín campusMVP Nuestra publicación electrónica, una vez al mes en tu buzón de correo.
 
Banner
Copyright © 2010 José Manuel Alarcón Aguín. All rights reserved.