Vimos de publicar un plugin para o xa framework WordPress co que abrimos conexión entre o theme Whatif (proxecto de Ecosistema Urbano) e un dispositivo Android (dende 1.6 ata 2.3.4 Gingerbread). Foi un parto longo, sobre todo porque o protocolo XML-RPC de WordPress ten limitacións importantes como a posibilidade de usar Custom Taxonomies ou os Custom Post Types. Tivemos que escribir código no plugin para habilitar estas novas funcións que forman parte do Framework Whatif.
A APP Android, que tamén foi programada no Estudo Pumpún, foi escrita seguindo o traballo da orixinal WordPress for Android e permite, entre outras…
“[…] introducir y etiquetar mensajes desde cualquier lugar, detectando automáticamente tu posición o dejándote elegirla, e incluyendo la posibilidad de adjuntar una fotografía en el mismo momento de publicar. También permite la consulta del contenido por ubicación, etiquetas, galería imágenes o lista de mensajes.”
Como o seu propio nome indica, é a aplicación móbil de Whatif, concibida para consultar e publicar entradas desde calquera lugar, cunha interfaz secuencial similar pero adaptada á pantalla dun smartphone. Esta aplicación conéctase con calquera instalación da versión web de Whatif, sincronizando con esta os textos da interfaz e os contidos.
É o interface entre a máquina Android e o Framework Whatif. Son varias as funcións que incorpora e que foron necesarias para habilitar esta comunicación entre máquinas:
*Activa automaticamente o protocolo XML-RPC de publicacion remota en wordpress (por defecto ven desactivado).
*Ampla os métodos de entrada via protocolo XML-RPC (como a posibilidade de ler dinámicamente taxonomías especiáis).
*Permite a publicación de novos post que incorporan estas Custom Taxonomies.
*incorpora miniaturas na lista de post que se visualizan no panel de control de WordPress.
*Define as dimensións por defecto da miniatura saltándose a configuracioón por defecto de WordPress.
__
Por exemplo, esta función ben simple, activa o protocolo XML-RPC do WordPress si non estivera activado.
1 2 3 | // AUTOMATICALLY TURNS THE XML-RPC PROTOCOL ON IN WORDPRESS // ACTIVA AUTOMATICAMENTE EL PROTOCOLO XML-RPC DE PUBLICACION REMOTA EN WORDPRESS update_option('enable_xmlrpc', '1'); |
Este outro cacho de código engade esa vista de miniaturas á lista de entradas no wordpress. Engade unha columna á dereita e dunha ollada permite coñecer cales post levan asociada unha imaxe (moi importante para o modo de visualización de imaxes da APP Android)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | // ADD TUMBNAILS IN MANAGE POST/PAGES LIST // INCORPORA MINIATURAS EN LA LISTA DE POST QUE SE VISUALIZA EN EL PANEL DE CONTROL DE WORDPRESS if ( !function_exists('AddThumbColumn') && function_exists('add_theme_support') ) { // for post and page add_theme_support('post-thumbnails', array( 'post', 'page' ) ); function AddThumbColumn($cols) { $cols['thumbnail'] = __('Thumbnail'); return $cols; } function AddThumbValue($column_name, $post_id) { $width = (int) 60; $height = (int) 60; if ( 'thumbnail' == $column_name ) { // thumbnail of WP 2.9 $thumbnail_id = get_post_meta( $post_id, '_thumbnail_id', true ); // image from gallery $attachments = get_children( array('post_parent' => $post_id, 'post_type' => 'attachment', 'post_mime_type' => 'image') ); if ($thumbnail_id) $thumb = wp_get_attachment_image( $thumbnail_id, array($width, $height), true ); elseif ($attachments) { foreach ( $attachments as $attachment_id => $attachment ) { $thumb = wp_get_attachment_image( $attachment_id, array($width, $height), true ); } } if ( isset($thumb) && $thumb ) { echo $thumb; } else { echo __('None'); } } } // for posts add_filter( 'manage_posts_columns', 'AddThumbColumn' ); add_action( 'manage_posts_custom_column', 'AddThumbValue', 10, 2 ); // for pages add_filter( 'manage_pages_columns', 'AddThumbColumn' ); add_action( 'manage_pages_custom_column', 'AddThumbValue', 10, 2 ); } |
E atención a estoutro que permite automatizar a Featured Image de cada artigo/post. Unha das formas de visualización de propostas/artigos da aplicación para Android é a través das imaxes que os usuarios toman da rúa con seus teléfonos. Cando o teléfono saca unha foto (ou adxunta unha da galería persoal), pégase ó artigo que está publicando e a imaxe envíase no momento da publicación. Pois ben, este cacho de código que se pode ver a continuación, permite que anque unha imaxe non se defina como Featured Image nun artigo/post de WordPress, a función colle a primeira imaxe do post e a define como Featured Image, o que permite navegar a través das imaxes e tamén visualizar a lista delas na propia lista de artigos no wordpress.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | // CONVERTIR AUTOMATICAMENTE LA PRIMERA IMAGEN ASOCIADA A UN POST EN IMAGEN DESTACADA if ( function_exists( 'add_theme_support' ) ) { add_theme_support( 'post-thumbnails' ); function easy_add_thumbnail() { global $post; $already_has_thumb = has_post_thumbnail(); if (!$already_has_thumb) { $attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" ); if ($attached_image) { foreach ($attached_image as $attachment_id => $attachment) { add_post_meta($post->ID, '_thumbnail_id', $attachment_id, true); } } } } // fin funcion add_action('the_post', 'easy_add_thumbnail'); // hooks added to set the thumbnail when publishing too add_action('new_to_publish', 'easy_add_thumbnail'); add_action('draft_to_publish', 'easy_add_thumbnail'); add_action('pending_to_publish', 'easy_add_thumbnail'); add_action('future_to_publish', 'easy_add_thumbnail'); } else { function eat_fail_requirements() { echo "<!-- Easy Add Thumbnail activated, but your WordPress doesn't support add_theme_support function -->"; } add_action('wp_head', 'eat_fail_requirements'); } |
E para rematar, aquí tedes o código completo do Plugin que incorpora un bo lote de funcións para ampliar as características do Protocolo XML-RPC. Unha morea de novas funcións que permiten incorporar os grandes pasos que deu o Framework WordPress neste último ano: a incorporación de tipos de post e a incorporación de taxonomías personalizadas que convirten, cando menos, un sistema de blog ordenado cronolóxicamente, nun potente CMS cuxos límites están na cabeza de quen traballa con eles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | < ?php /* Plugin Name: WhatIf Android Plugin URI: http://whatif.es/ Description: Enable connection between -What If Framework and Android APP-If. Author: Pumpun Dixital Version: 1.0 Author URI: http://pumpun.com */ /* This plugin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* 88888888ba 88888888ba, 88 88 88 88 "8b 88 `"8b "" "" ,d 88 88 ,8P 88 `8b 88 88 88aaaaaa8P' 88 88 88,dPYba,,adPYba, 8b,dPPYba, 88 88 8b,dPPYba, 88 88 88 8b, ,d8 88 MM88MMM ,adPPYYba, 88 88""""""' 88 88 88P' "88" "8a 88P' "8a 88 88 88P' `"8a 88 88 88 `Y8, ,8P' 88 88 "" `Y8 88 88 88 88 88 88 88 88 d8 88 88 88 88 88 8P 88 )888( 88 88 ,adPPPPP88 88 88 "8a, ,a88 88 88 88 88b, ,a8" "8a, ,a88 88 88 88 .a8P 88 ,d8" "8b, 88 88, 88, ,88 88 88 `"YbbdP'Y8 88 88 88 88`YbbdP"' `"YbbdP'Y8 88 88 88888888Y"' 88 8P' `Y8 88 "Y888 `"8bbdP"Y8 88 88 88 */ // AUTOMATICALLY TURNS THE XML-RPC PROTOCOL ON IN WORDPRESS - ACTIVA AUTOMATICAMENTE EL PROTOCOLO XML-RPC DE PUBLICACION REMOTA EN WORDPRESS update_option('enable_xmlrpc', '1'); // CUSTOM XMLRPC METHODS AMPLIA LOS METODOS DE ENTRADA VIA PROTOCOLO XML-RPC, EL SISTEMA DE PUBLICACION REMOTO DE WORDPRESS add_filter( 'xmlrpc_methods', 'newMethods' ); function newMethods( $methods ) { $methods['wp.wifGetTaxonomies'] = 'wp_wifGetTaxonomies'; $methods['wp.wifGetAllTaxonomies'] = 'wp_wifGetAllTaxonomies'; $methods['wp.wifNewPost'] = 'wp_wifNewPost'; $methods['wp.wifGetRecentPosts'] = 'wp_wifGetRecentPosts'; $methods['wp.wifGetPage'] = 'wp_wifGetPage'; return $methods; } function wp_wifGetTaxonomies( $args ) { global $wp_xmlrpc_server; $wp_xmlrpc_server->escape($args); $blog_ID = (int) $args[0]; // for future use $username = $args[1]; $password = $args[2]; $tipo = $args[3]; if ( !$wp_xmlrpc_server->login( $username, $password ) ) return new IXR_Error( 401, $wp_xmlrpc_server->error->message ); $tags = array( ); if ( $all_tags = get_terms($tipo) ) { foreach( (array) $all_tags as $tag ) { $struct['tag_id'] = $tag->term_id; $struct['name'] = $tag->name; $struct['count'] = $tag->count; $struct['slug'] = $tag->slug; $tags[] = $struct; } } return $tags; } function wp_wifGetAllTaxonomies( $args ) { global $wp_xmlrpc_server; $wp_xmlrpc_server->escape($args); $blog_ID = (int) $args[0]; // for future use $username = $args[1]; $password = $args[2]; if ( !$wp_xmlrpc_server->login( $username, $password ) ) return new IXR_Error( 401, $wp_xmlrpc_server->error->message ); $tipo = "positivo"; $tags = array( ); if ( $all_tags = get_terms($tipo) ) { foreach( (array) $all_tags as $tag ) { $struct['tag_id'] = $tag->term_id; $struct['name'] = $tag->name; $struct['count'] = $tag->count; $struct['slug'] = $tag->slug; $struct['tipo'] = $tipo; $tags[] = $struct; } } $tipo = "negativo"; $tags_neg = array( ); if ( $all_tags = get_terms($tipo) ) { foreach( (array) $all_tags as $tag ) { $struct_neg['tag_id'] = $tag->term_id; $struct_neg['name'] = $tag->name; $struct_neg['count'] = $tag->count; $struct_neg['slug'] = $tag->slug; $struct_neg['tipo'] = $tipo; $tags_neg[] = $struct_neg; } } return array_merge($tags, $tags_neg); } // NEW POST WITH CUSTOM TAXONOMIES - PARA LA PUBLICACION DE NUEVOS POST CON CUSTOM TAXONOMIAS function wp_wifNewPost($args) { global $wp_xmlrpc_server; $wp_xmlrpc_server->escape($args); $blog_ID = (int) $args[0]; // we will support this in the near future $username = $args[1]; $password = $args[2]; $content_struct = $args[3]; $publish = isset( $args[4] ) ? $args[4] : 0; if ( !$user = $wp_xmlrpc_server->login($username, $password) ) return $wp_xmlrpc_server->error; $page_template = ''; if ( !empty( $content_struct['post_type'] ) ) { if ( $content_struct['post_type'] == 'page' ) { if ( $publish ) $cap = 'publish_pages'; elseif ('publish' == $content_struct['page_status']) $cap = 'publish_pages'; else $cap = 'edit_pages'; $error_message = __( 'Sorry, you are not allowed to publish pages on this site.' ); $post_type = 'page'; if ( !empty( $content_struct['wp_page_template'] ) ) $page_template = $content_struct['wp_page_template']; } elseif ( $content_struct['post_type'] == 'post' ) { if ( $publish ) $cap = 'publish_posts'; elseif ('publish' == $content_struct['post_status']) $cap = 'publish_posts'; else $cap = 'edit_posts'; $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' ); $post_type = 'post'; } else { // No other post_type values are allowed here return new IXR_Error( 401, __( 'Invalid post type.' ) ); } } else { if ( $publish ) $cap = 'publish_posts'; elseif ('publish' == $content_struct['post_status']) $cap = 'publish_posts'; else $cap = 'edit_posts'; $error_message = __( 'Sorry, you are not allowed to publish posts on this site.' ); $post_type = 'post'; } if ( !current_user_can( $cap ) ) return new IXR_Error( 401, $error_message ); // Check for a valid post format if one was given if ( isset( $content_struct['wp_post_format'] ) ) { $content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] ); if ( !array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) { return new IXR_Error( 404, __( 'Invalid post format' ) ); } } // Let WordPress generate the post_name (slug) unless // one has been provided. $post_name = ""; if ( isset($content_struct["wp_slug"]) ) $post_name = $content_struct["wp_slug"]; // Only use a password if one was given. if ( isset($content_struct["wp_password"]) ) $post_password = $content_struct["wp_password"]; // Only set a post parent if one was provided. if ( isset($content_struct["wp_page_parent_id"]) ) $post_parent = $content_struct["wp_page_parent_id"]; // Only set the menu_order if it was provided. if ( isset($content_struct["wp_page_order"]) ) $menu_order = $content_struct["wp_page_order"]; $post_author = $user->ID; // If an author id was provided then use it instead. if ( isset($content_struct["wp_author_id"]) && ($user->ID != $content_struct["wp_author_id"]) ) { switch ( $post_type ) { case "post": if ( !current_user_can("edit_others_posts") ) return(new IXR_Error(401, __("You are not allowed to post as this user"))); break; case "page": if ( !current_user_can("edit_others_pages") ) return(new IXR_Error(401, __("You are not allowed to create pages as this user"))); break; default: return(new IXR_Error(401, __("Invalid post type."))); break; } $post_author = $content_struct["wp_author_id"]; } $post_title = isset( $content_struct['title'] ) ? $content_struct['title'] : null; $post_content = isset( $content_struct['description'] ) ? $content_struct['description'] : null; $post_status = $publish ? 'publish' : 'draft'; if ( isset( $content_struct["{$post_type}_status"] ) ) { switch ( $content_struct["{$post_type}_status"] ) { case 'draft': case 'private': case 'publish': $post_status = $content_struct["{$post_type}_status"]; break; case 'pending': // Pending is only valid for posts, not pages. if ( $post_type === 'post' ) $post_status = $content_struct["{$post_type}_status"]; break; default: $post_status = $publish ? 'publish' : 'draft'; break; } } $post_excerpt = isset($content_struct['mt_excerpt']) ? $content_struct['mt_excerpt'] : null; $post_more = isset($content_struct['mt_text_more']) ? $content_struct['mt_text_more'] : null; $tags_input = isset($content_struct['mt_keywords']) ? $content_struct['mt_keywords'] : null; $taxonomytags_input = isset($content_struct['wp_taxonomytags']) ? $content_struct['wp_taxonomytags'] : null; $taxonomy_tipo = isset($content_struct['wp_taxonomy']) ? $content_struct['wp_taxonomy'] : null; if ( isset($content_struct["mt_allow_comments"]) ) { if ( !is_numeric($content_struct["mt_allow_comments"]) ) { switch ( $content_struct["mt_allow_comments"] ) { case "closed": $comment_status = "closed"; break; case "open": $comment_status = "open"; break; default: $comment_status = get_option("default_comment_status"); break; } } else { switch ( (int) $content_struct["mt_allow_comments"] ) { case 0: case 2: $comment_status = "closed"; break; case 1: $comment_status = "open"; break; default: $comment_status = get_option("default_comment_status"); break; } } } else { $comment_status = get_option("default_comment_status"); } if ( isset($content_struct["mt_allow_pings"]) ) { if ( !is_numeric($content_struct["mt_allow_pings"]) ) { switch ( $content_struct['mt_allow_pings'] ) { case "closed": $ping_status = "closed"; break; case "open": $ping_status = "open"; break; default: $ping_status = get_option("default_ping_status"); break; } } else { switch ( (int) $content_struct["mt_allow_pings"] ) { case 0: $ping_status = "closed"; break; case 1: $ping_status = "open"; break; default: $ping_status = get_option("default_ping_status"); break; } } } else { $ping_status = get_option("default_ping_status"); } if ( $post_more ) $post_content = $post_content . " |
This entry was written by Plugins and tagged android, app, whatif. Leave a comment or view the discussion at the permalink.
, posted on 9 Xullo, 2011 at 16:58, filed underUn traballo encargado por Ouvirmos.com deunos a oportunidade de construir un interface multimedia para coñecer a obra do escritor galego Lois Pereiro, a quen adica este ano o Día das Letras Galegas. O interface está composto por 2 elementos:
*Unha PANTALLA TÁCTIL de gran tamaño flotando horizontalmente sobre unha caixa negra
*Un MURO VERTICAL de 2×3.5 metros sobre o que se desprega unha liña de tempo da súa vida e obra incluíndo pequenas pantallas incrustadas (marcos dixitais).
Estase estes días programando o interactivo, que correrá nun monitor de 46″ ELO 2Touch cun ordenador incrustado (sin ventiladores), o monitor utiliza unha tecnoloxía basada en son : “Acoustic Pulse Recognition”.
Vaise traballar sobre un Celeron de dobre núcleo con tan só 1gb de ram, suficinte para mover un navegador como Opera 11 ou Chrome 11 dev cunha aplicación programada enteiramente en HTML5 (Canvas) incluíndo jQuery, CSS3 e posiblemente Jsonp. Nuns días publicamos máis detalles do proceso.
VER OS DETALLES DO PROXECTO
This entry was written by Blog, Hardware and tagged apr, blog, canvas, css3, html5, jquery, touch. Leave a comment or view the discussion at the permalink.
, posted on 22 Febreiro, 2011 at 12:35, filed underIniciamos este repositorio de códigos e outros intanxibles que circulan polo Estudio Pumpún. Dende este web bruta e de lectura directa, contaremos os triunfos e os fracasos deste célula de desenvolvemento de aplicacións que vive e traballa en Vigo.
This entry was written by Blog and tagged blog, escoitar, estudio. Leave a comment or view the discussion at the permalink.
, posted on 18 Febreiro, 2011 at 13:51, filed under