Fuentes web
Entradas
Comentarios

Leído en elwebmaster,

A veces, con poco, hacemos mucho. Optimizaciones que no llevan más 5 minutos son muchas veces las que llevan a nuestro sitio al siguiente nivel, mejorando increíblemente la usabilidad y accesibilidad para nuestros usuarios.

Podemos hacer ajustes en el backend (optimizando consultas a la base de datos, por ejemplo), en el HTML, el Javascript o usando sprites. Esta vez concentrémonos en los estilos CSS con 7 tips súper importantes.

Cambiar el color del texto seleccionado

En Firefox, Safari y Opera puedes cambiar el aburrido color por default por otro más acorde con los colores de tu sitio, que destaque más y ayude a la visualización:

PLAIN TEXT

  1. ::selection { background:#c3effd; color:#000; /* Safari y Opera */ }
  2. ::-moz-selection { background:#c3effd; color:#000; /* Firefox */ }

Prevenir que Firefox "salte" al mostrar y ocultar la barra de scroll

Firefox tiene el hábito de mostrar y ocultar la barra de scroll vertical según si el contenido de una página sobrepasa o no el alto de la ventana (el "fold"). En sitios interactivos con contenido dinámico que pueda cambiar una y otra vez, este efecto provoca un salto desagradable. De la siguiente manera podemos prevenirlo:

PLAIN TEXT

  1. html { overflow-y:scroll; }

Aplicar esquinas redondeadas a los contenedores

Además de ser un cambio agradable en Firefox y Safari, también ayuda a identificar mejor los elementos.

PLAIN TEXT

  1. input { -moz-border-radius:10px; -webkit-border-radius:10px; }

Setear los saltos de página para imprimir

Mucha gente querrá imprimir el texto de tu sitio web. No olvides ordenar los temas en las hojas ubicando saltos de página para no cortar una oración a la mitad:

PLAIN TEXT

  1. .page-break { page-break-before:always; }

Íconos específicos en atributos

Para diferenciar links de descarga (ejemplo: archivos formato PDF) o links externos. Tú decides.

PLAIN TEXT

  1. a[href$='.pdf'] { padding:0 20px 0 0; background:transparent url(/graphics/icons/pdf.gif) no-repeat center right; }

Cambiar el cursor por un puntero en los links y botones

Importante "detalle" que a muchos se les escapa. Hacer que el cursor del mouse se convierta en un puntero (la manito señalando) al pasarlo por encima de botones, links y demás elementos clickeables mejorará muchísimo la experiencia del usuario:

PLAIN TEXT

  1. input[type=submit],label,select,.pointer { cursor:pointer; }

Hacer cliqueable toda el área alrededor de los links

Seteando la propiedad "display" en block en los links (a, anchor) de una lista, conseguiremos que el usuario no tenga que posar el cursor del mouse sobre el texto específicamente para poder hacer clic, sino que quede linqueado todo el recuadro contenedor.

PLAIN TEXT

  1. #navigation li a { display:block; }

¿Qué otros tips rápidos nos recomiendas?

Enlaces | David Walsh Blog | elwebmaster

Leído en elwebmaster,

El Codex de WordPress explica el funcionamiento de los plugins desde una perspectiva de referencia, pero la mejor manera de aprender a desarrollarlos es ver ejemplos de código real.

Este tutorial es una introducción al desarrollo de un plugin básico que utiliza PHP para guardar y recuperar datos de la base de datos de WordPress para mostrarlos en el sitio.

Crea un archivo PHP

Primero, crea un archivo PHP en una carpeta con un nombre único, esta carpeta residirá en la misma carpeta que los otros plugins, por lo que no puede tener un nombre que se repita.

Este será el archivo dónde se guardará todo nuestro scripting para el plugin.

Funciones para usuarios y administradores

En el archivo PHP, comencemos creando dos funciones:

PLAIN TEXT

  1. function miwidget_public($args = false) {
  2. }
  3. function miwidget_admin() {
  4. }

Nuestro widget, a modo de ejemplo, se llama "Mi Widget", que se referenciará como "miwidget_" en el código.

Estas dos funciones son el esqueleto para el código PHP que se ejecutará cuando el usuario visita la parte pública de tu sitio WordPress – en cualquier página que pongas el widget (vamos a llegar a eso en breve), así como la parte de administración cuando un usuario admin arrastra el widget a un panel lateral (bajo la sección Apariencia » Widgets):

Siéntete libre de incluir cualquier código PHP en ambas funciones – lo que sea que desees ejecutar.

En la función de administrador, básicamente estarás programando la creación de un formulario HTML para que los usuarios puedan controlar los ajustes relacionados con el widget:

En la imagen de arriba, se les pide a los usuarios información pertinente para hacer una llamada API (puedes poner cualquier cosa aquí- esto es sólo un ejemplo).

Por lo que, para los principiantes, la función administradora podría lucir así:

PLAIN TEXT

  1. function miwidget_admin() {
  2. $options_site = get_option("widget_miwidget_site");
  3. ?>
  4. <p>
  5. Your Software URL:
  6. <input type="text" name="p_link" id="p_link" value="<?php echo $options_site["p_link"]; ?>" style="width:99%;" />
  7. </p>
  8. <p>
  9. Your Software Username:
  10. <input type="text" name="username" id="username" value="<?php echo $options_site["username"]; ?>" style="width:99%;" />
  11. </p>
  12. <p>
  13. Your Software Password:
  14. <input type="password" name="password" id="password" value="<?php echo $options_site["password"]; ?>" style="width:99%;" />
  15. </p>
  16. <?php
  17. }

Nota, de forma específica, los atributos value para cada elemento <input>.

Referenciamos la variable $options_site, que se declara antes de que el HTML tenga salida. $options_site llama a una función WordPress, get_option(), que devuelve valores desde la base de datos.

Si te estás preguntando cómo los valores llegan a la base de datos en primer lugar, lo hacen llamando a otra función de WordPress: update_option().

Hechémosle un vistazo a la sintaxis que guarda los valores de la base de datos:

PLAIN TEXT

  1. update_option("widget_miwidget_site", $options_site);

La función update_option() acepta dos parámetros. El primero es el nombre único que utilizarás para referenciar estos valores de base de datos en tus scripts. El segundo es la variable que estás guardando en la base de datos. Puedes pasar un array aquí también, lo que es útil para colecciones de valores relacionados.

Tus valores se guardan en la tabla de base de datos wp_options. Los valores enviados como arrays serán serializados.

Puedes crear tantas opciones distintas como desees, y todas se pueden guardar en la base de datos.

Continuando con la función administradora, cuando alguien complete los detalles y haga clic en "Guardar", deberías llamar a la función update_option y pasar los valores a esta.

Así que, para modificar un poco la función admin:

PLAIN TEXT

  1. function miwidget_admin() {
  2. $options_site = get_option("widget_miwidget_site");
  3. if ($_SERVER["REQUEST_METHOD"] == "POST") {
  4. $options_site = array(
  5. "p_link" => $_POST["p_link"],
  6. "username" => $_POST["username"],
  7. "password" => $_POST["password"],
  8. );
  9. update_option("widget_miwidget_site", $options_site);
  10. }
  11. else {
  12. ?>
  13. <p>
  14. Your Software URL:
  15. <input type="text" name="p_link" id="p_link" value="<?php echo $options_site["p_link"]; ?>" style="width:99%;" />
  16. </p>
  17. <p>
  18. Your Software Username:
  19. <input type="text" name="username" id="username" value="<?php echo $options_site["username"]; ?>" style="width:99%;" />
  20. </p>
  21. <p>
  22. Your Software Password:
  23. <input type="password" name="password" id="password" value="<?php echo $options_site["password"]; ?>" style="width:99%;" />
  24. </p>
  25. <?php
  26. }
  27. }

Aquí nos fijamos si el botón "Guardar" fue presionado (if ($_SERVER["REQUEST_METHOD"] == "POST")), y de ser así, creamos un array para los valores del formulario y actualizamos la base de datos.

En tu función public, puedes devolver los valores de la base de datos para que se muestren en el sitio:

PLAIN TEXT

  1. function miwidget_public($args = false) {
  2. $options_site = get_option("widget_miwidget_site");
  3. echo $options_site["html"];
  4. }

Es así de simple.

Dado que hay un array "html" en $options_site, esto mostrará el contenido "html" en la sidebar en la parte pública de tu sitio WordPress.

Llama al código necesario para registrar el plugin en WordPress

Hay algunas cosas más que necesitamos hacer antes de que el widget sea reconocido y funcione en el sistema de WordPress.

Al final de tu archivo PHP, incluye el siguiente código:

PLAIN TEXT

  1. function widget_miwidget_init() {
  2. register_sidebar_widget("Mi Widget", "widget_miwidget_public");
  3. register_widget_control("Mi Widget", ‘widget_miwidget_admin’);
  4. }
  5. add_action("plugins_loaded", "widget_miwidget_init");

Esto cargará el plugin en la página de administración, para que los usuarios puedan activarlo.

¡Y eso son los pasos básicos!

Lean la documentación oficial de WordPress sobre plugins para más detalles.

Enlace | Pain in the Tech | elwebmaster

Leído en intenta,

La sustitución de imágenes mediante CSS es, a grandes rasgos, una técnica de sustitución de un elemento de terxto de una pagina por una imagen. Quizá uno de los ejemplos más clarificadores sería a la hora de incluir el logo en una web. Es posible que desees utilizar una etiqueta <h1> y texto por accesibilidad y los beneficios en cuanto a SEO, pero a la vez, y por razones estéticas, te gustaría mostrar tu logo y no el texto.

Un ejemplo:

texto planocopiar

  1. <h1 id="logo">
  2. <span>Intenta
  3. </h1>
<h1 id="logo">
 <span>Intenta
</h1>

y el css:

texto planocopiar

  1. h1#logo {
  2. width: 250px;
  3. height: 25px;
  4. background-image: url(logo.gif);
  5. }
  6. h1#logo span {
  7. display: none;
  8. }
h1#logo {
 width: 250px;
 height: 25px;
 background-image: url(logo.gif);
}
h1#logo span {
 display: none;
}

En CSS-Tricks puedes encontrar el análisis de nueve de estas técnicas, cómo se realizan y las ventajas y desventajas de cada una.

Enlaces | Nine Techniques for CSS Image Replacement | intenta

1Kb CSS Grid

Leído en intenta,

Los Frameworks de CSS se han vuelto muy populares en los últimos tiempos. La mayoría de ellos tratan de cubrir varios aspectos: un sistema de cuadrícula, un restablecimiento de estilo, la tipografía básica, los estilos de los formularios, etc. Otros se centran exclusivamente en la retícula, pero aún así generan un CSS hinchado.

Éste es un framework CSS diferente. Su misión es ser ligero y crearnos únicamente una retícula con nuestras necesidades y con la que empezar a trabajar. Todo en menos de 1Kb (662 bytes en realidad).

Enlaces | 1KbGrid | intenta |

Leído en ThinkWasabi,

Para ciertas búsquedas, y en mi caso personal, delicious es infinitamente mejor que Google

No sé dónde leí el otro día que “delicious estaba muerto”. Bueno, a juzgar por la cantidad de enlaces que allí se guardan a diario yo diría que más bien no. Sigue siendo el lugar de almacenamiento de enlaces por excelencia y, bien utilizado, puede ser una herramienta muy útil para trabajar y organizarnos. Y para buscar.

Yo utilizo delicious desde hace cuatro años y pico y habitualmente lo combino con Evernote (aquí expuse una fórmula para hacerlo). Ahí guardo los artículos “a largo plazo”.

Pero hoy quería hablaros de delicious como buscador. Porque de un tiempo a esta parte he visto cómo, para ciertas búsquedas, ha ido sustituyendo paulatinamente a Google. ¿Por qué? Porque en delicious está lo mejor de lo mejor. Contenido especialmente elegido, clasificado y etiquetado por los usuarios a mano, de forma expresa y deliberada. En Google está todo. Lo bueno y lo malo.

Sobre todo cuando quiero buscar información sobre una técnica específica, un tutorial concreto, las claves o una review de una aplicación, una guía explicativa o una recopilación de lo mejor, voy directamente a delicious. ¿Por qué? Porque sé que:

1. Lo voy a encontrar antes. Y no por la velocidad sino por la menor cantidad de ruido. Hay menos links y son MUY precisos.

2. Los enlaces —las páginas— que voy a encontrar allí tienen más “calidad”. Personas como tú y como yo un día decidieron que ese artículo o página merecía la pena por su contenido y su redacción y la guardaron.

3. El indicador con el número de personas que han guardado esa página me ayuda a identificar, dentro de los resultados, “lo mejor de lo mejor”.

4. Las etiquetas que han colocado usuarios como yo me ayudan todavía más a encontrar lo que busco, ya que al introducir una búsqueda, luego puedo filtrar los resultados por etiquetas.

5. Visualmente la página de resultados de delicious me resulta más cómoda. Es más limpia, concisa y directa que la de Google.

Naturalmente que si quiero buscar algo general, como la página web de una empresa o un restaurante, los links de una peli en Rapidshare o la letra de una canción en suajili, voy a Google como todo bicho viviente. Pero poco a poco en ciertas búsquedas (que generalmente además en mi caso personal tienen que ver con el diseño, el diseño web y la fotografía) voy directamente a delicious. Y cada día estoy más contento por lo cómodo y eficiente que me resulta.

Si le vas a dar una oportunidad a delicious como buscador “para algunas cosas”, para una mayor comodidad te recomiendo que optes por alguna solución que acelere tus búsquedas. Por ejemplo con alguna de estas alternativas:

  • Instala el motor de búsqueda de delicious en tu navegador.
  • Busca mediante YubNub con tu navegador o tu lanzador de aplicaciones (el trigger es ds)
  • Instala un bookmark de búsquedas en la barra de tu navegador.
  • Instala en local alguna aplicación que facilite la operación. Yo en Mac conozco Delibar.

Enlace | ThinkWasabi

Leído en sentidoweb,

Hace tiempo hice un script para PHP que permitía postear en WordPress usando Jabber (por ejemplo GTalk). Ahora he mejorado un poco el script para que admita poner categorías (si no las hay, las crea) y subir imágenes mediante una URL (ajustándolo a un ancho máximo).

Existen distintas palabras claves para separar los distintos elementos del post dentro del texto que se envía: titulo, contenido, tags, categorias e image. Las distintas secciones se separan con ‘##’ para diferenciarlas unas de otras y se separarán por dos puntos ‘:’ formando pares clave:valor. Un ejemplo para escribir en el IM sería el siguiente:

titulo:Titulo del post##contenido:Lorem Ipsum... con todo el HTML que querramos##tags:etiqueta1, etiqueta2, etiqueta3##categorías:Categoria1,Categoria2#image:http://servidor.com/ruta/imagen.png

El código principal es el siguiente:

<?php
 
require './XMPPHP/XMPP_Old.php';
require './xmlrpc/xmlrpc.inc';
 
$blog_usuario = 'usuario';
$blog_contraseña = 'contraseña';
$blog_url = 'dominio.com';
$blog_xmlrpc_path = '/xmlrpc.php';
$blog_puerto = 80;
 
$post_tags = array('tag-defecto');
$post_separador = '##';
$post_titulo_defecto = 'Titulo';
$post_insertar_p = false;
 
$jabber_host = 'dominio_jabber.com';
$jabber_contraseña = 'contraseña';
$jabber_usuario = 'usuario';
$jabber_puerto = 5222;
 
// Ancho máximo para la imágen
$max_width = 540;
 
function post($message) {
 global $blog_usuario;
 global $blog_contraseña;
 global $blog_url;
 global $blog_xmlrpc_path;
 global $blog_puerto;
 global $post_tags;
 global $post_separador;
 global $post_titulo_defecto;
 global $post_insertar_p;
 global $max_width;
 
 $message = mb_convert_encoding($message, 'ISO-8859-1', 'UTF-8');
 $aux = explode($post_separador, $message);
 if (count($aux) == 1) {
 $titulo = $post_titulo_defecto;
 $contenido = $message; 
 $tags = implode(',', $post_tags);
 } else {
 foreach($aux as $item) {
 $pair = explode(':', $item, 2);
 $var = $pair[0];
 $$var = $pair[1];
 }
 }
 
 if ($post_insertar_p) {
 $contenido = implode("\n", array_map(create_function('$e', 'return "<p>$e</p>";'), explode("\n", $contenido)));
 }
 
 if (isset($image)) {
 $img_content = file_get_contents($image);
 $im = imagecreatefromstring($img_content);
 $w = imagesx($im);
 $h = imagesy($im);
 $imgtype = exif_imagetype($image);
 if ($w > $max_width) {
 $image_p = imagecreatetruecolor($max_width, intval($h*$max_width/$w));
 imagecopyresampled($image_p, $im, 0, 0, 0, 0, $max_width, intval($h*$max_width/$w), $w, $h);
 ob_start();
 imagepng($image_p);
 $img_content = ob_get_contents();
 ob_end_clean();
 $imgtype = IMAGETYPE_PNG;
 $w = $max_width;
 $h = intval($h*$max_width/$w);
 }
 $imgname = "img".time().image_type_to_extension($imgtype);
 $f = new xmlrpcmsg('metaWeblog.newMediaObject',
 array(php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode(array('name'=>$imgname, 'bits'=>new xmlrpcval($img_content, 'base64'))))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->setDebug(0);
 $r=&$c->send($f);
 if(!$r->faultCode()) {
 $v=$r->value();
 $datos = simplexml_load_string($v->serialize());
 $url = $datos->xpath('//member/name[. ="url"]/following-sibling::*/string');
 $contenido = '<img src="'.$url[0].'" width='.$w.'" height='.$h.'" />'.$contenido;
 } else {
 return "Error a la hora de subir la imagen: $image [".$r->faultString()."]";
 } 
 }
//$contenido .= mb_convert_encoding($contenido, 'UTF-8');
 $f = new xmlrpcmsg('wp.getUsersBlogs',
 array(php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->setDebug(0);
 $r=&$c->send($f);
 if(!$r->faultCode()) {
 $v=$r->value();
 $datos = simplexml_load_string($v->serialize());
 $blogid = $datos->xpath('//member/name[. ="blogid"]/following-sibling::*/string');
 $blogid = is_array($blogid) ? (string) $blogid[0] : (string) $blogid; 
 $f = new xmlrpcmsg('metaWeblog.newPost',
 array(php_xmlrpc_encode($blogid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode(array('title'=>$titulo, 'description'=>$contenido, 'mt_keywords'=>$tags)), php_xmlrpc_encode(1))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->request_charset_encoding = 'UTF-8';
 $c->setDebug(0);
 $r=&$c->send($f);
 if($r->faultCode()) {
 return "Ha habido un error al intentar crear un nuevo post [".$r->faultString()."]";
 } else {
 $datos = simplexml_load_string($r->serialize());
 $postid = $datos->xpath('//value/string');
 $postid = is_array($postid) ? (string) $postid[0] : (string) $postid; 
 
 $f = new xmlrpcmsg('metaWeblog.getPost',
 array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->setDebug(0);
 $r=&$c->send($f);
 if($r->faultCode()) {
 return "Ha habido un error al intentar recuperar información sobre el post insertado [".$r->faultString()."]";
 } else {
 $datos = simplexml_load_string($r->serialize());
 $permalink = $datos->xpath('//member/name[. ="permaLink"]/following-sibling::*/string');
 $permalink = is_array($permalink) ? (string) $permalink[0] : (string) $permalink; 
 $title = $datos->xpath('//member/name[. ="title"]/following-sibling::*/string');
 $title = is_array($title) ? (string) $title[0] : (string) $title; 
 if (isset($categorias)) {
 $f = new xmlrpcmsg('mt.getCategoryList',
 array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->setDebug(0);
 $r=&$c->send($f);
 if(!$r->faultCode()) {
 $datos = simplexml_load_string($r->serialize());
 $catsblog = $datos->xpath('//struct');
 foreach(explode(',', $categorias) as $cat) {$cats[$cat] = null;}
 foreach($catsblog as $cat) {
 foreach($cats as $_cat=>$val) {
 if (strtolower((string) $cat->member[1]->value->string) == strtolower($_cat)) {
 $cats[$_cat] = (string) $cat->member[0]->value->string;
 }
 }
 }
 
 foreach($cats as $cat=>$val) {
 if (!$val) {
 $f = new xmlrpcmsg('wp.newCategory',
 array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode(array('name'=>$cat, 'slug'=>str_replace(' ', '_', strtolower($cat)), 'parent_id'=>1, 'description'=>'')))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->setDebug(0);
 $r=&$c->send($f);
 if(!$r->faultCode()) {
 $datos = simplexml_load_string($r->serialize());
 $catid = (string) $datos->xpath('//int');
 $cats[$cat] = $catid;
 } else {
 return "Ha habido un error a la hora de crear la categoría $cat";
 }
 }
 }
 foreach($cats as $val) {
 $catlist[] = array('categoryId'=>$val);
 }
 $f = new xmlrpcmsg('mt.setPostCategories',
 array(php_xmlrpc_encode($postid), php_xmlrpc_encode($blog_usuario), php_xmlrpc_encode($blog_contraseña), php_xmlrpc_encode($catlist))
 );
 $c=new xmlrpc_client($blog_xmlrpc_path, $blog_url, $blog_puerto);
 $c->setDebug(0);
 $r=&$c->send($f);
 if($r->faultCode()) {
 return "Hubo un error a la hora de modificar las categorías del post";
 }
 } else {
 return "Ha habido un error al intentar recuperar las categorias del blog";
 }
 }
 return "Se ha publicado '$title': $permalink"; 
 }
 }
 
 } else {
 return "Ha habido un error al intentar recuperar información sobre el blog [".$r->faultString()."]";
 }
}
 
 
 
//Use XMPPHP_Log::LEVEL_VERBOSE to get more logging for error reports
//If this doesn't work, are you running 64-bit PHP with < 5.2.6?
 
$conn = new XMPPHP_XMPPOld($jabber_host, $jabber_puerto, $jabber_usuario, $jabber_contraseña, 'xmpphp', $jabber_host, false, 
XMPPHP_Log::LEVEL_ERROR);
$conn->autoSubscribe();
$conn->useEncryption(false);
 
try {
 $conn->connect();
 while(!$conn->isDisconnected()) {
 $payloads = $conn->processUntil(array('message', 'presence', 'end_stream', 'session_start'));
 foreach($payloads as $event) {
 $pl = $event[1];
 switch($event[0]) {
 case 'message': 
 if (trim($pl['body']) == '') break;
 $conn->message($pl['from'], $body=post($pl['body']), $type=$pl['type']);
 if($pl['body'] == 'quit') $conn->disconnect();
 if($pl['body'] == 'break') $conn->send("</end>");
 break;
 case 'presence':
 // print "Presence: {$pl['from']} [{$pl['show']}] {$pl['status']}\n";
 break;
 case 'session_start':
 //print "Empezamos\n";
 $conn->getRoster();
 $conn->presence($status="Asonesss jefeeeeeee!");
 break;
 }
 }
 }
} catch(XMPPHP_Exception $e) {
 echo 'ERROR:';
 die($e->getMessage());
}

Podéis bajaros el código aquí.

Enlace | sentidoweb

Leído en sentidoweb,

El otro día mi compañero David y yo estábamos mirando cómo hacer que cuando publicamos en Twitter desde la aplicación, no salga “from API”. Por lo que buscando buscando, encontré un plugin para WordPress que lo implementaba y luego David encontró la documentación necesaria.

Tan solo hay que indicar unas cabeceras HTTP y crear un XML que contiene información que leerá Twitter.

Enlace | sentidoweb

Leído en sentidoweb,

Facebook Connect es una API de FB que nos permite usar nuestra cuenta de FB en otras webs. A mi personalmente, la ayuda que ofrece FB no me apasiona demasiado, y cuando quieres realizar algo con Facebook Connect te tienes que pelear bastante con cosas que haces mal o que te faltan por hacer. Por ello, creo que este tutorial es bastante interesante para aquellos que quieren desarrollar algo con FB Connect y no saben por dónde empezar.

El tutorial nos mostrará los siguientes puntos:

  1. Crear una aplicación en Facebook
  2. Copiar en tu sitio el fichero xd_receiver.htm
  3. Descargar la API PHP de FB en tu web
  4. Modificar tu tabla de usuarios
  5. Crear una página para loguearse con FB Connect
  6. Enlazar a fbclogin.php desde tu login
  7. Otros puntos a seguir

Facebook Connect Tutorial

Enlaces | PHPDeveloper.org | sentidoweb

Leído en sentidoweb,

Me ha gustado el ejemplo para mostrar en tu web las visitas y las páginas vistas de tu web como muestra Feedburner los suscritores que tienes en el feed. Para mostrarlo haremos uso de la librería GAPI, la cual accede a los datos que ofrece Google Analytics:

&lt;?php
define('ga_email','yourGoogleEmail');
define('ga_password','yourGooglePass');
define('ga_profile_id','yourProfileID');
 
require 'gapi.class.php';
$ga = new gapi(ga_email,ga_password);
$ga-&gt;requestReportData(ga_profile_id,array('browser','browserVersion'),array('pageviews'));
?&gt;

El resto será darle estilo a los datos obtenidos.

FeedCount-Like Google Analytics Counter

Enlaces | Script & Style | sentidoweb

Leído en anieto2k,

MarketCSS es un framework CSS desarrollado por Jose Castro que nos permite simplificar la tarea de maquetar en CSS.

// Referencia "lh" + número de 80 a 200 de 10 en 10
// Interlineado de 80% a 200% de 10 en 10; por ejemplo "lh120"
<div class="lh120"></div>

// Referencia "b" negrita
<div class="b"></div>

// Referencia "i" cursiva
<div class="i"></div>

// Referencia "n" normal
<div class="n"></div>

// Referencia "u" subrayado
<div class="u"></div>

Mediante un sistema de referencias, que usaremos como clases en los elementos de nuestro HTML, obtendremos los resultados preestablecidos ahorrándonos una buena cantidad de código CSS.

Enlaces | ceslava | anieto2k

Entradas antiguas »