viernes, 4 de junio de 2010 (Hace 149 dias)

Un par de modificaciones simples a las funciones de WordPress que imprimen el paginador (ver al pie de la página principal, donde aparece «Apuntes más antiguos», ahora aparece un numerito de fondo) para que incluyan el número de página a la que apunta el enlace. Me pareció mas cómodo, intuitivo, etc., etc…
Solo hay que tocar dos funciones (get_previous_posts_link y get_next_posts_link) para incluir una etiqueta nueva conteniendo el número y a continuación via CSS se formatea para que quede bonito, y todo sin gastar ni un kb en bitmaps.

Así es como se ha quedado la función get_next_posts_link en /raiz_wp/wp_includes/link_template.php
function get_next_posts_link( $label = 'Next Page »', $max_page = 0 ) {
global $paged, $wp_query;
if ( !$max_page ) {
$max_page = $wp_query->max_num_pages;
}
if ( !$paged )
$paged = 1;
$nextpage = intval($paged) + 1;
if ( !is_single() && ( empty($paged) || $nextpage <= $max_page) ) {
$attr = apply_filters( 'next_posts_link_attributes', '' );
return '<a href="' . next_posts( $max_page, false ) . "\" $attr title=\"Ir a la página $nextpage\">". preg_replace('/&([^#])(?![a-z]{1,8};)/', '&$1', $label) .'</a><small id="numeroSiguiente" class="numeroPaginaFondo">'.$nextpage.'</small>';
}
}

Así es como se ha quedado la función get_previous_posts_link en /raiz_wp/wp_includes/link_template.php
function get_previous_posts_link( $label = '« Previous Page' ) {
global $paged;
if ( !is_single() && $paged > 1 ) {
$paginaanterior = intval($paged) - 1;
$attr = apply_filters( 'previous_posts_link_attributes', '' );
return '<small id="numeroAnterior" class="numeroPaginaFondo">'.$paginaanterior.'</small><a href="' . previous_posts( false ) . "\" $attr title=\"Ir a la página $paginaanterior\">". preg_replace( '/&([^#])(?![a-z]{1,8};)/', '&$1', $label ) .'</a>';
}
}

y en el CSS algo como
.paginador .numeroPaginaFondo { font-weight:bold; display:inline; position:absolute; top:-55px; font-size:102px; color:#eed;z-index:-1;}
.paginador .numeroPaginaFondo#numeroAnterior {right:0px;}
.paginador .numeroPaginaFondo#numeroSiguiente {left:0px;}

Creo que queda más bonico del tó que unicamente el enlace del texto.

miércoles, 2 de junio de 2010 (Hace 151 dias)

He modificado la función get_calendar de este WordPress 2.9.0 ubicada en /raiz_wp/wp_includes/general_template.php para reemplazar el titulo del més por una lista de mes-año (numero de apuntes).
Creo que con esto se mejora bastante la navegación por los apuntes antiguos y aunque me suena de algún plugins que hace algo parecido vereis que se pueden ahorrar algunos recursos simplemente añadiendo unas líneas a la función.
La función get_calendar ha quedado de la siguiente manera (la parte corregida/modificada está advertida, el resto de la función es la original … creo… :) )
function get_calendar($initial = true) {
global $wpdb, $m, $monthnum, $year, $wp_locale, $posts;
$cache = array();
$key = md5( $m . $monthnum . $year );
if ( $cache = wp_cache_get( 'get_calendar', 'calendar' ) ) {
if ( is_array($cache) && isset( $cache[ $key ] ) ) {
echo $cache[ $key ];
return;}
}
if ( !is_array($cache) )
$cache = array();
// Quick check. If we have no posts at all, abort!
if ( !$posts ) {
$gotsome = $wpdb->get_var("SELECT 1 as test FROM $wpdb->posts WHERE post_type = 'post' AND post_status = 'publish' LIMIT 1");
if ( !$gotsome ) {
$cache[ $key ] = '';
wp_cache_set( 'get_calendar', $cache, 'calendar' );
return;
}
}
ob_start();
if ( isset($_GET['w']) )
$w = ''.intval($_GET['w']);
// week_begins = 0 stands for Sunday
$week_begins = intval(get_option('start_of_week'));
// Let's figure out when we are
if ( !empty($monthnum) && !empty($year) ) {
$thismonth = ''.zeroise(intval($monthnum), 2);
$thisyear = ''.intval($year);
} elseif ( !empty($w) ) {
// We need to get the month from MySQL
$thisyear = ''.intval(substr($m, 0, 4));
$d = (($w - 1) * 7) + 6; //it seems MySQL's weeks disagree with PHP's
$thismonth = $wpdb->get_var("SELECT DATE_FORMAT((DATE_ADD('${thisyear}0101', INTERVAL $d DAY) ), '%m')");
} elseif ( !empty($m) ) {
$thisyear = ''.intval(substr($m, 0, 4));
if ( strlen($m) < 6 )
$thismonth = '01';
else
$thismonth = ''.zeroise(intval(substr($m, 4, 2)), 2);
} else {
$thisyear = gmdate('Y', current_time('timestamp'));
$thismonth = gmdate('m', current_time('timestamp'));
}
$unixmonth = mktime(0, 0 , 0, $thismonth, 1, $thisyear);
// Get the next and previous month and year with at least one post
$previous = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
FROM $wpdb->posts
WHERE post_date < '$thisyear-$thismonth-01'
AND post_type = 'post' AND post_status = 'publish'
ORDER BY post_date DESC
LIMIT 1");
$next = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
FROM $wpdb->posts
WHERE post_date > '$thisyear-$thismonth-01'
AND MONTH( post_date ) != MONTH( '$thisyear-$thismonth-01' )
AND post_type = 'post' AND post_status = 'publish'
ORDER BY post_date ASC
LIMIT 1");
/* translators: Calendar caption: 1: month name, 2: 4-digit year */
$calendar_caption = _x('%1$s %2$s', 'calendar caption');
echo '<table id="wp-calendar" summary="' . esc_attr__('Calendar') . '">';
echo '<caption>';
//INICIO seccion cambiada
$unixPrimero=mktime(0,0,0,4,5,2003);
$anoAnterior="";
$unixUltimo=time();
echo '<select onchange="document.location.href=this.value;">';
while ( $unixPrimero < $unixUltimo ) {
$apuntesMensuales = $wpdb->get_var("SELECT COUNT(*) FROM $wpdb->posts WHERE post_date LIKE '%".date('Y-m-', $unixPrimero)."%' AND post_status='publish' LIMIT 1");
$anoEnCurso=date('Y', $unixPrimero);
if($apuntesMensuales > 0) {
if( $anoAnterior != $anoEnCurso ) {
if($anoAnterior != "") echo "</optgroup>";
echo "<optgroup label=\"$anoEnCurso\">";
$anoAnterior=$anoEnCurso;
}
echo "<option value=\"/".date('Y/m', $unixPrimero)."\"";
if( date('Y/m', $unixPrimero) == "$thisyear/$thismonth" ) echo " selected=\"selected\" ";
echo ">".$wp_locale->get_month(date("m",$unixPrimero))." - ".date('Y', $unixPrimero)." (".$apuntesMensuales.")</option>\n";
}
else {
if( $anoAnterior != $anoEnCurso ) {
if($anoAnterior != "") echo "</optgroup>";
echo "<optgroup label=\"$anoEnCurso\">";
$anoAnterior=$anoEnCurso;
}
echo "<option disabled>".$wp_locale->get_month(date("m",$unixPrimero))." - ".date('Y', $unixPrimero)." (0)</option>";
}
$unixPrimero=$unixPrimero+2678400;
}
echo "<option value=\"/\"";
if( date('Y/m', $unixUltimo) == "$thisyear/$thismonth" ) echo " selected=\"selected\" ";
echo ">".$wp_locale->get_month(date("m",$unixUltimo))." - ".date('Y', $unixUltimo)." (actualmente)</option>\n";
echo '</select>';
// $mesSegundo=$primerMes + 2592000;
// echo date('F Y', $mesSegundo);
// $mesActual="";
// echo sprintf($calendar_caption, $wp_locale->get_month($thismonth), date('Y', $unixmonth));
//FIN seccion cambiada
echo '</caption>
<thead>
<tr>';
$myweek = array();
for ( $wdcount=0; $wdcount<=6; $wdcount++ ) {
$myweek[] = $wp_locale->get_weekday(($wdcount+$week_begins)%7);
}
foreach ( $myweek as $wd ) {
$day_name = (true == $initial) ? $wp_locale->get_weekday_initial($wd) : $wp_locale->get_weekday_abbrev($wd);
$wd = esc_attr($wd);
echo "\n\t\t<th abbr=\"$wd\" scope=\"col\" title=\"$wd\">$day_name</th>";
}
echo '
</tr>
</thead>
<tfoot>
<tr>';
if ( $previous ) {
echo "\n\t\t".'<td abbr="' . $wp_locale->get_month($previous->month) . '" colspan="3" id="prev"><a href="' .
get_month_link($previous->year, $previous->month) . '" title="' . sprintf(__('View posts for %1$s %2$s'), $wp_locale->get_month($previous->month),
date('Y', mktime(0, 0 , 0, $previous->month, 1, $previous->year))) . '">« ' . $wp_locale->get_month_abbrev($wp_locale->get_month($previous->month)) . '</a></td>';
} else {
echo "\n\t\t".'<td colspan="3" id="prev" class="pad"> </td>';
}
echo "\n\t\t".'<td class="pad"> </td>';
if ( $next ) {
echo "\n\t\t".'<td abbr="' . $wp_locale->get_month($next->month) . '" colspan="3" id="next"><a href="' .
get_month_link($next->year, $next->month) . '" title="' . esc_attr( sprintf(__('View posts for %1$s %2$s'), $wp_locale->get_month($next->month) ,
date('Y', mktime(0, 0 , 0, $next->month, 1, $next->year))) ) . '">' . $wp_locale->get_month_abbrev($wp_locale->get_month($next->month)) . ' »</a></td>';
} else {
echo "\n\t\t".'<td colspan="3" id="next" class="pad"> </td>';
}
echo '
</tr>
</tfoot>
<tbody>
<tr>';
// Get days with posts
$dayswithposts = $wpdb->get_results("SELECT DISTINCT DAYOFMONTH(post_date)
FROM $wpdb->posts WHERE MONTH(post_date) = '$thismonth'
AND YEAR(post_date) = '$thisyear'
AND post_type = 'post' AND post_status = 'publish'
AND post_date < '" . current_time('mysql') . '\'', ARRAY_N);
if ( $dayswithposts ) {
foreach ( (array) $dayswithposts as $daywith ) {
$daywithpost[] = $daywith[0];
}
} else {
$daywithpost = array();
}
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false || strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'camino') !== false || strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'safari') !== false)
$ak_title_separator = "\n";
else
$ak_title_separator = ', ';
$ak_titles_for_day = array();
$ak_post_titles = $wpdb->get_results("SELECT post_title, DAYOFMONTH(post_date) as dom "
."FROM $wpdb->posts "
."WHERE YEAR(post_date) = '$thisyear' "
."AND MONTH(post_date) = '$thismonth' "
."AND post_date < '".current_time('mysql')."' "
."AND post_type = 'post' AND post_status = 'publish'"
);
if ( $ak_post_titles ) {
foreach ( (array) $ak_post_titles as $ak_post_title ) {
$post_title = esc_attr( apply_filters( 'the_title', $ak_post_title->post_title ) );
if ( empty($ak_titles_for_day['day_'.$ak_post_title->dom]) )
$ak_titles_for_day['day_'.$ak_post_title->dom] = '';
if ( empty($ak_titles_for_day["$ak_post_title->dom"]) ) // first one
$ak_titles_for_day["$ak_post_title->dom"] = $post_title;
else
$ak_titles_for_day["$ak_post_title->dom"] .= $ak_title_separator . $post_title;
}
}
// See how much we should pad in the beginning
$pad = calendar_week_mod(date('w', $unixmonth)-$week_begins);
if ( 0 != $pad )
echo "\n\t\t".'<td colspan="'. esc_attr($pad) .'" class="pad"> </td>';
$daysinmonth = intval(date('t', $unixmonth));
for ( $day = 1; $day <= $daysinmonth; ++$day ) {
if ( isset($newrow) && $newrow )
echo "\n\t</tr>\n\t<tr>\n\t\t";
$newrow = false;
if ( $day == gmdate('j', (time() + (get_option('gmt_offset') * 3600))) && $thismonth == gmdate('m', time()+(get_option('gmt_offset') * 3600)) && $thisyear == gmdate('Y', time()+(get_option('gmt_offset') * 3600)) )
echo '<td id="today">';
else
echo '<td>';
if ( in_array($day, $daywithpost) ) // any posts today?
echo '<a href="' . get_day_link($thisyear, $thismonth, $day) . "\" title=\"" . esc_attr($ak_titles_for_day[$day]) . "\">$day</a>";
else
echo $day;
echo '</td>';
if ( 6 == calendar_week_mod(date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear))-$week_begins) )
$newrow = true;
}
$pad = 7 - calendar_week_mod(date('w', mktime(0, 0 , 0, $thismonth, $day, $thisyear))-$week_begins);
if ( $pad != 0 && $pad != 7 )
echo "\n\t\t".'<td class="pad" colspan="'. esc_attr($pad) .'"> </td>';
echo "\n\t</tr>\n\t</tbody>\n\t</table>";
$output = ob_get_contents();
ob_end_clean();
echo $output;
$cache[ $key ] = $output;
wp_cache_set( 'get_calendar', $cache, 'calendar' );
}

Podeis ver como queda echando un vistazo al calendario que aparece en estas páginas, en la columna de la derecha.

miércoles, 17 de febrero de 2010 (Hace 256 dias)

Al final, lo que iban a ser unos «añadidos» en la web han pasado a convertirse en la versión 9.0 de Cuaderno de campo.
Estéticamente los cambios no son muchos, los que más lo noten serán los usuarios de Internet Explorer (me armé de valor he instalé internet explorer 7.0 en el VMPlayer, … que lamentable navegador el puto IE…).
Básicamente he optimizado bastante el código de la versión anterior, especialmente el CSS pero tambien javascript y bastante PHP especialmente el plugin FAlbum, las plantillas de estilo y alguna funcion de WordPress.
Ahora las páginas pensan algo menos, menos accesos a base de datos y menos plugins. He homogeneizado las areas de fotografia, video y panorámicas, las estadísticas del blog, etc…
En fín. No lo he probado muy a fondo en todos los navegadores, pero creo que se vé igual en Konqueror, Firefox, IE, Opera y G. Chrome

viernes, 5 de febrero de 2010 (Hace 268 dias)

Pequeños cambios de diseño en la web.

Shortlinks: Al entrar en cualquier apunte aparece a la derecha, entre otros, el «shortlink» ó «enlace reducido» de dicho apunte, muy cómodo para cuando queremos insertar un enlace a un apunte dentro de un correo, sms, etc… En breve lo insertaré también en el cuadro desplegable debajo de cada apunte.

Microhuerta: Un sección que desaparece, la de Minihuerta, que deja de estar visible en el sidebar (si bien sigue siendo accesible via url). Doy por finalizado el experimento de la huerta en casa: este año la huerta se trasladará al campo, con lo que me ahorraré tener que subir 30-40 litros de agua todos los dias a la terraza, mejorará el crecimiento de las plantas, consecuentemente la cosecha, etc, etc…
No descarto de todas formas reabrir la sección más adelante. Teniendo en cuenta que en el campo ya tenemos internet, siempre cabe la posibilidad de colocarle una webcam a las tomateras y transmitir al mundo y en tiempo real el crecimiento de un pepino. :)

Fotografía panorámica: Una nueva sección accesible desde el sidebar apunta a una galería de fotografías panorámicas 360º. Basicamente funciona esta sección de modo identico las de fotografía y vídeo, excepto que está «especializada» en las fotografías panorámicas visibles a través de una aplicación flash.
He tenido que hacer un pequeño cacao de contenidos para conseguir integrarlo en el Cuaderno, pero creo que ha quedado resulton y relativamente cómodo. La explicación técnica despues del «sigue…«. Sigue leyendo…

lunes, 19 de octubre de 2009 (Hace 12 dias)

A mediados de este pasado verano descubrimos en la finca familiar de los Simonetes una señal wifi. Algún vecino había instalado un punto de acceso a internet y aunque muy débil (con un portatil había que hacer filigranas para siquiera detectar la señal) la situación era terriblemente tentadora, demasiado: tener un ordenador en el campo conectado a internet y sirviendo las imágenes capturadas por Motion.

El primer dia monté un viejo ordenador a base de desechos he instalé openSuse 11.1 (la grabadora no quería leer el DVD de 10.3). El segundo dia construí una parabólica con restos de la tulipa de una vieja lámpara y el pié telescopico de un micrófono. El tercer dia instalé aircrack. El cuarto día ya había crackeado la contraseña de acceso WPA-PSK del vecino (no habiendo nunca antes aircrack, resultó terriblemente rápido y sencillo. Dá que pensar).

Para no dar la nota demasiado, ni fastidiar su invento (y el mío), hice un programita al que llamaremos Modo-Gitano-Escondido (MGE), el cual básicamente consistía en escanear periodicamente la red a la que estabamos conectados y si descubriamos que había alguien conectado nos desconectabamos, esperabamos un tiempo prudencial y «asomabamos el hocico cual alimaña vampirizadora», cuando no había nadie conectado volviamos a entrar.

Aquelló funcionó una buena temporada, y podía incluso acceder via ssh al ordenador del campo haciendo un tunel inverso con ayuda del ordenador de casa. Pero sinceramente: era un coñazo. ¿sabeis que las Nintendo se conectan cada día a las 4 de la mañana a internet (vaya usted a saber para que cosa) ?
Había dias que el ordenador se conectaba solo de madrugada un par de horas, momento en que aprovechaba para enviar cientos de imagenes capturadas durante el periodo de desconexión.

Asi es que compré una parabólica comercial (más diametro, mas potencia) y me dispuse a crackear todo lo que hubiera a mi alcance. La diferencia entre la parabólica casera y la comercial, además de en el diametro 30 ctms la primera y 80 la segunda, fué bestial: de pillar 6-7 puntos de acceso a pillar más de los que caben en pantalla. Llegué a coger conexiones a 11 kmts (Cartagena, campo de futbol).

En estas estaba cuando conseguí entrar al AP (punto de acceso) de una empresa situada a varios kilometros de distancia (no estoy seguro de donde estaba, pero a no menos de 5 kilometros). Entonces me dije: coño, pues para conectarme en plan gitano a una empresa en la quinta puñeta me conecto con casa de mis padres que aunque está a 8 ktms en linea recta (según Google Maps) hay (muy importante) vision directa (sin obstaculos).
Y eso es lo que hice, y funcionó, a la primera! Sigue leyendo…

lunes, 29 de junio de 2009 (Hace 124 dias)

Esta es la entradilla que se podía leer en Meneame hoy enlazando a una noticia de La voz de Galicia.

La regeneración de las antiguas canteras, minas o espacios afectados por las grandes infraestructuras evitaría la liberación a la atmósfera de todo el dióxido de carbono que se emite en Galicia. ¿Cómo? Mediante la cubierta de los espacios degradados con suelo creado a partir de residuos, que presenta una gran capacidad para estabilizar la materia orgánica que retiene el carbono en la tierra. Son los llamados tecnosoles, una tecnología ya conocida pero que ha perfeccionado el equipo de Edafología de la Universidade de Santiago (…)

Ya he comentado por aqui en alguna ocasión la opinión que me merecen estos «eco-inventos» pero en el caso de esta entradilla es especialmente llamativo: basta con cambiar una palabra para dejar en evidencia lo ridículo del asunto, y sin que el «descubrimiento» carezca de sentido.
Podría quedar algo asi:

La regeneración de las antiguas canteras, minas o espacios afectados por las grandes infraestructuras evitaría la liberación a la atmósfera de todo el dióxido de carbono que se emite en Galicia. ¿Cómo? Mediante la cubierta de los espacios degradados con suelo creado a partir de residuos, que presenta una gran capacidad para estabilizar la materia orgánica que retiene el carbono en la tierra. Son los llamados «árboles», una tecnología ya conocida pero que ha perfeccionado el equipo de Edafología de la Universidade de Santiago (…)

Para colmo, lo de llamar «tecnosoles» a los «arboles» le dá un toque como muy tecnologicamente moderno, si es de lo que se trata.

Cuaderno de campo es un blog desarrollado y mantenido por Trebol-a y en el que escriben Trebol-a, Miguel, Merche y Mónica
Si quieres saber algo más sobre los autores acude a la página acerca-de, si quieres contactar con alguno de nosotros hazlo a través de contactar ó de Google+

Creative Commons: Todo el contenido de la web (imágenes, textos, vídeos, a excepción de aquellas obras de otros autores enlazados por Cuaderno de Campo) se acoge a los términos expresados en la licencia Creative Commons