WordPress: Refresh W3 Total Cache when saving or updating a PODs item

When you create or edit a PODs element in Worpdress, W3TC refresh the cache of the modified page. But sometimes you also show its content on home page or other kind of page, and in those cases you need to flush the cache through the plugin admin panel. I was tired of doing this task every time I update something, so now I have a code to do it automatically.

You have to add this code in your function.php theme file.

// REFRESH W3 Total Cache AFTER SAVE/UPDATE
function refreshCacheOnSave($pieces, $is_new_item) {
    if (function_exists('w3tc_pgcache_flush')) {
        w3tc_pgcache_flush();
        w3tc_minify_flush();
    }
}

// refresh cache after PODs creation/save/update
add_filter('pods_api_post_save_pod_item', 'refreshCacheOnSave', 10, 2);
    add_action( 'pods_api_post_save_pod_item', $pieces, $is_new_item );

add_filter('pods_api_post_create_pod_item', 'refreshCacheOnSave', 10, 2);
    add_action( 'pods_api_post_create_pod_item', $pieces, $is_new_item );

add_filter('pods_api_post_edit_pod_item', 'refreshCacheOnSave', 10, 2);
    add_action( 'pods_api_post_edit_pod_item', $pieces, $is_new_item );

The process of create my first Mobile App with AngularJs & PhoneGap

meeting-time-cost_detail

March 1, 2014: Thinking about the new App

Lately I’m feeling a little bit outdated in my job, because some of the new company projects are based on technologies which I’ve never used before like:

That’s why I want to start a new personal project base on some of those technologies, to learn to use them and became a better front-end developer. After thinking some days about it, I’ve decided to create a Mobile App to check the money that a meeting is costing, based on the amount of people in the meeting and theirs salaries. I choose this app because:

  • Although this idea is no new at all on the markets, I didn’t found a nice app to do this task, at least on Android, all of them are ugly (in my opinion, of course), so I think I can create a better and nicer app.
  • It’s quite easy to develop, so I can focus on learning the new technologies, instead of wasting time in doing other kind of things.
  • I will use it, and I also  hope other people will do. My company, Paradigma Tecnológico,  it’s a fabulous company to work in , but like most of companies has a lot of meetings everyday. I know meetings are necessary, but I hate when a meeting take to long and people start talking about things not related with the meeting´s topic. I hope this app can make people try to finish earlier their meeting, saving money for the company, and time for their employees.

It will be an hybrid app (one app that can be install on IOS, Android, Windows Phone,… without the need to make a source code for each platform) compile with PhoneGap. I choose PhoneGap because:

  • It is easier and faster for me. I’m a front developer, so I feel very comfortable with HTML, JS & CSS.
  • I think  learn PhoneGap will be more useful for my job that learning native code (IOS or Android). My company is full of great developers that can code much better than me native apps.
  • This App is small and it doesn’t use phone specific capabilities, so I hope that it would be as efficient with PhoneGap that with native code.
  • Get more devices with less effort. I’ll create just one app, but almost everyone will be able to download it and use it.
  • I want that the app also can be accessible through the web browser. PhoneGap uses standard technologies like HTML, CSS and JavaScript, so the app must be able to run as a web page.  So people will be able to use it with out the need of download it and install it on their devices.

leer mas

Seminarios de WordPress en Paradigma: Introducción y curso avanzado

Hace ya unos cuantos meses tuve la suerte de poder impartir dos seminarios sobre WordPress a mis compañeros de Paradigma Tecnológico.

Introducción a WordPress

Con este primer seminario podréis ver una breve introducción a lo que es WordPress, conociendo sus ventajas y sus riesgos. También aprovechamos para hacer un sencillo caso práctico, creando una web de ejemplo, y viendo como editar y administrar dicha web.

WordPress avanzado. Las tripas de WordPress y sus Plugins

Segundo seminario de esta serie, con el que entramos en WordPress más en profundidad. Con este curso podrás ver y conocer:

  • La estructura de ficheros de WordPress y de sus plantillas,
  • ¿Qué es el loop y como funciona?
  • Mi lista de plugins indispensables,
  • y algunas medidas de seguridad para proteger WordPress de ataques indeseados.

WordPress supervitaminado: PODs Framework

Tercer y último seminario de esta serie. Por desgracia todavía no he podido sacar tiempo para impartirlo, pero espero que pronto pueda impartirlo, y así dar por terminado esta trilogía del WordPress.

CSS transform: El movimiento de las órbitas

Hacer animaciones con CSS mola, y a día de hoy es algo que todavía no está muy extendido entre los maquetadores. El soporte de navegadores ya es mas que aceptable, y deberíamos de empezar a aplicarlos en nuestras maquetas.

En la última versión de la web de Paradigma optamos por hacer uso de las animaciones CSS en algunas de sus páginas. El caso más significativo es el de la página de contacto o la 404, donde quisimos simbolizar varios grupos de órbitas en movimiento.

Tras hablar con algunos de mis colegas, y darme cuenta de que pensaban que estaba hecho con JavaScript, pensé que podría ser interesante explicar como se hizo  (por lo menos no pensaron que estaba hecho en Flash).

orbits

leer mas

Pods WordPress > Mi guía

Como ya sabéis me encanta usar Pods Framework para WordPress, pero siempre gasto demasiado tiempo volviendo a buscar como hacer las queries, mostrar ciertos campos, … Por este motivo, voy a intentar crearme una guía con las porciones de código que más uso en mis proyectos, y así poder usarla como guía de consulta en el futuro. Con un poco de suerte, quizás también sea útil para ti.

Tipos de Pods

Yo suelo usar dos: Custom Post Type (ampliar los post habituales de Worpdress) o los Advanced Content Type (tablas nuevas que no extienden de ningún elemento de WordPress)

Según usemos uno cambiará ligeramente las queries de busqueda:

Custom Post Type

$params = array(
  'where' =>   't.post_status="Publish"',
  'orderby' => 'position.meta_value+0 ASC',
  'limit' =>   -1  // -1 = no limit in items per page
);

$mypod = pods( 'podsTypeName', $params );
$params = array(
  // show it if wordpress status is publish & it belongs to current type
  'where' => 't.post_status="Publish" AND podTypeName.field_id="'.$typeId.'"'
);

Advanced Content Type

$params = array(
  'where' => 'active=1',
  'orderby' => 'position+0 ASC',
  'limit' => -1  // -1 = no limit in items per page
);

$mypod = pods( 'podsTypeName', $params );

Loop

while ( $mypod->fetch() ) {
  echo $mypod->data->row['ID'];
  echo $mypod->display('title');

  echo wpautop($mypod->display('content'));
    // Changes double line-breaks in the text into HTML paragraphs (<p>...</p>)

  // multiselect field:
  echo $mypod->get_field('categories');
  $array = $mypod->field('categories.category_id');
     foreach ($array as &$item) {
       echo $item;
     }

  // Image
  $portfolio_image = $portfolio->get_field('image');
  echo $portfolio_image[0]['guid'];
}
// Total records in the loop
$openingData->total();

Single Records

$slug = pods_v( 'last', 'url' );
// antes se usaba: $slug = pods_url_variable('last');

$params = array( 'where' => 'post_name = "'.$slug.'"' );
$mypod = pods( 'podsTypeName', $params );

Poco a poco iré ampliando estas porciones de código.

Espero que os sea de ayuda

Campos de fecha

$datetime = explode(" ", $mypod->display( 'start_date' ));
$date = explode("-", $datetime [0]);
$time = explode(":", $datetime [1]);
echo date(get_option('date_format'), mktime($time[0], $time[1], 0, $date[1], $date[0], $date[2]));

Centrar texto verticalmente con CSS

Parece mentira, pero todavía tengo muchos problemas para centrar el texto verticalmente dentro de un div. Hoy he visto una solución que me ha gustado en Stack Overflow.

<div>
  <span>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</span>
</div>
div {
  width: 250px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}

span {
  display: inline-block;
  vertical-align: middle;
  line-height: normal;
}

De este modo conseguimos lo que vemos en esta imagen, que los botones siempre tengan la misma altura, y queden bien con una o dos líneas.

double-line-button

WordPress search: Customizar búsqueda para encontrar diferentes tipos de entradas

Hoy he tenido la necesidad de customizar la búsqueda por defecto de Worpdress, que usamos en la web corporativa de Paradigma, para poder mostrar en una misma página de resultados diferentes tipos de entradas/posts/artículos.

Aunque he visto que hay un par de plugins que hacen esta funcionalidad, he optado por adaptar la búsqueda por medio de funciones en el fichero functions.php de mi tema.

El primer problema es que para poder realizar estas búsquedas no podemos usar los campos por defecto de wordpress (por ejemplo el título o el contenido), así que necesitamos ejecutar una acción que añada un campo oculto por cada uno de los campos que necesitaremos para la búsqueda:

add_action( "save_post", "add_title_custom_field");

function add_title_custom_field($postid){
    // since we removed the "s" from the search query, we want to create
    // some custom fields for every post_title & post_content
    update_post_meta($postid, "_post_title", $_POST["post_title"]);
    update_post_meta($postid, "_post_content", $_POST["post_content"]);
}

Está acción se ejecutará cada vez que salvemos un post, y tendremos que tenerla siempre activa, para que todas las entradas que actualicemos tengan esta información. Pero ¿qué podemos hacer con todos las entradas que ya tenemos creadas en nuestro wordpress? ¿Es necesario salvar cada una por separado? Pues por suerte no. Con esta función que os pongo a continuación, y que basta con que sea ejecutada UNA ÚNICA VEZ, actualizaremos todo el contenido de nuestra base de datos, sin necesidad de tener que ir salvando uno a uno cada artículo.

// create new fields on every post of your wordpress
function addNewFieldsToPosts() {
    global $post;
    $args = array(
        'numberposts' => -1,
         //  set here each post type you want to search
        'post_type' => array( 'post', 'portfolio', 'openings', 'events' )
        );
    $the_query = get_posts( $args );
    if ($the_query) {
        foreach ($the_query as $post) {
            update_post_meta($post->ID, "_post_title", $post->post_title);
            update_post_meta($post->ID, "_post_content", $post->post_content);
        }
    }
}
wp_reset_query();
add_action('wp_head', 'addNewFieldsToPosts');

Si no ejecutamos estas dos funciones no encontraremos resultados en nuestras búsquedas.

Vale, si , muy bonito, pero… ¿Y la función necesaria para adaptar la búsqueda de WordPress? Pues aquí la teneis:

// CUSTOM SEARCH RESULTS
function custom_search_query( $query ) {
    $custom_fields = array(
        // put all the meta fields you want to search for here
        "_post_title", // we must add this fields on update_post_meta function
        "_post_content",
        "long_description"
    );
    $searchterm = $query->query_vars['s'];
    // we have to remove the "s" parameter from the query,
    // because it will prevent the posts from being found
    $query->query_vars['s'] = "";
    if ($searchterm != "") {
        //  set here each post type you want to search
        $query->set('post_type', array('post', 'pages', 'events', 'portfolio' ));
        $meta_query = array('relation' => 'OR');
        foreach($custom_fields as $cf) {
            array_push($meta_query, array(
                'key' => $cf,
                'value' => $searchterm,
                'compare' => 'LIKE'
            ));
        }
        $query->set("meta_query", $meta_query);
    };
}
add_filter( "pre_get_posts", "custom_search_query");

Diferenciar resultados por tipo de entrada

En nuestra página de resultados de búsqueda (search.php) podremos diferenciar cada resultado por su tipo de este modo:

$post_type = get_post_type( $post_id );

Espero que os sean de utilidad estas funciones. A mi me han salvado el día.

Mi combinación ganadora para Internet Explorer 8

Cuando empezamos un nuevo proyecto siempre queremos aprovechar todo el potencial de HTML5, pero por desgracia no podemos olvidarnos de nuestro fiel amigo Internet Explorer 8.

Por suerte, ya hace tiempo que desterramos de nuestras maquetas a sus predecesores: Internet Explorer 6 y 7, pero IE8 se quedará con nosotros a tomar otro par de copitas más antes de irse.

Gracias a frameworks como bootstrap, foundation o paraGridma, podemos tener un esqueleto de aplicación moderno, pero perfectamente funcionar en IE8. En el desarrollo de paraGridma, el mayor problema que me encontre para adaptarlo a IE8 fue el de que aceptara algunas de las novedades de HTML5 y sobretodo el uso de media-queries.

Finalmente, opte por la combinación de dos librerías: html5shiv y respond.js.

Podemos incluir estas librerías por el método condicional tradicional:

<!--[if lt IE 9]>
  <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
  <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
<![endif]-->

O también podemos incluirlo de esta otra forma.

<?php
  // because new Internet Explorer develop tools don't proccess conditional comments
  $conditionalComments = '';
  if (strpos($_SERVER['HTTP_USER_AGENT'],'MSIE 8.0') !== false) {
    $conditionalComments .= '<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>';
    $conditionalComments .= '<script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>';
  }

  echo $conditionalComments;
?>

Es recomendable usar esta segundo método si estamos testando la web con las develop tools de explorer 11, ya que incomprensiblemente este navegador no entiende los comentarios condicionales cuando emulamos una versión anterior del navegador.

Y hasta aquí mi consejo de hoy. Espero que os haya sido de utilidad.

Adaptar el alto y ancho al embeber un iframe de Youtube, Vimeo, …

Uno de los problemas que surgen al hacer una web responsible es el de querer mostrar un iframe de Youtube, Vimeo, etc… Los iframes que nos facilitan estos proveedores suelen tener asociado una anchura y altura fijas, por lo que difícilmente se van a adaptar a nuestro flamante diseño fluido. Lo bueno, es que ya hace tiempo alguien muy sesudo se encontró con este problema, y le dio una solución de lo más sencilla, para que al altura del iframe siempre sea relativa a su anchura.

video_responsive

<div class="responsiveContent">
    <iframe src="//www.youtube.com/embed/_veOIvMWazU" 
            allowfullscreen="" frameborder="0"></iframe>
</div>

 

.responsiveContent {
  position: relative;
  height: 0;
  overflow: hidden;
  padding-bottom: 56.2%;
  margin-bottom: 20px;
}
.responsiveContent iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Como vemos en el código la solución pasa por:

  • Quitar toda referencia a width o height en la etiqueta del propio iframe
  • Crear un contenedor para el iframe con altura 0
  • La altura vendrá definida por el padding que le demos al contenedor. Al darle el padding en porcentage, la altura siempre sera el x% de la anchura del padre.

Podéis ver este ejemplo funcionando en mi querido framework paragridma.

Lo único que tendréis que tener en cuenta es el aspect ratio del vídeo que queráis mostrar. En caso de no coincidir se deberá de modificar el padding del contenedor.

Espero que este truqui os sea de utilidad.

Mi experiencia de wordpress Multiidioma con el plugin Polylang

En varias ocasiones he tenido que crear sitios wordpress en varios idiomas. Hasta ahora venía usando el plugin WPML, pero el hecho de que se haya convertido en un plugin de pago y que me surjieran algunos bugs, me hizo buscar alguna alternativa.

Al final he dado con el plugin Polylang, y de momento mi experiencia es muy buena. En la parte negativa puedo destacar la falta de documentación, que todavía se encuentra en una fase temprana de desarrollo (aunque su funcionamiento de momento es correcto), y que la integración con PODs no es todavía completa.

Algunos de mis problemas de momento:

Lo estoy usando junto con PODs, y al mostrar los registros de PODs muestra todos los que encuentran, sin importar el idioma:

En su día cree esta entrada en el foro de PODs


/*= GET CASES STUDIES */
$params = array(
'where' => 'active.meta_value = 1',
'orderby' => 'position ASC',
'limit' => 4
);

// Get the Pods object
$mypod = pods( 'case_studies', $params );

// Loop through the items returned
while ( $mypod->fetch() ) {
?>

<? echo $mypod->display( 'title' ); ?>
<? echo $mypod->display( 'short_description' ); ?>

Para solucionarlo he tenido que hacer esta modificación:


while ( $mypod->fetch() ) {
// it show all matched pods, from all language,
  // so we check if current pod is in current language
$post_id = $mypod->data->row['ID'];
$translated_post_id = pll_get_post($post_id, pll_current_language());

// if both id are equal, then it is in the right laguage
if ($post_id == $translated_post_id) {
?>

<? echo $mypod->display( 'title' ); ?>
<? echo $mypod->display( 'short_description' ); ?>

}
}

Link a la home page con el idioma correcto


<?= pll_home_url(); ?>

No se me muestran algunas páginas

Este es el error que más me preocupa, y estoy francamente preocupado por que se me pueda reproducir en producción

De repente (no se que desencadena el fallo) los links a las páginas de worpdress muestran el contenido del index.php en lugar de mostrar el page.php

Hasta ahora lo he podido solucionar desactivando y volviendo a activar los plugins de PODs, y de WordPress SEO