Esta página esta siendo tocada. Disculpa si las cosas no se ven como siempre.

Etiqueta: wordpress

  • Me ocupo de mantener el WordPress que hace funcionar danirod.es actualizado, pero no siempre le presto atención a las novedades. Recientemente, mirando las novedades de WordPress en los últimos 12 meses, me encontré que está despegando una función en WordPress llamada Edición de sitio completa o Full Site Editing.

    Esta función permite tratar un sitio web como si fuese un SquareSpace o una de estas páginas web, porque deja editar completamente todos los aspectos del tema, incluyendo los bloques que mostrar en la página de portada o en la página de una entrada. Se basa en la tecnología de Gutenberg, pero llevada más allá para permitir ver todo el sitio web como si fuese una zona editable controlada por bloques. Algunos de estos bloques son los esperables para una plantilla de sitio, como por ejemplo el bloque «Bucle de entradas de blog», el bloque «Título de entrada» o el bloque «Fecha de publicación».

    Me estoy ocupando de probar esta nueva función en un sitio de staging y no termino de saber cómo sentirme al respecto. Por un lado, me resulta una forma bastante fresca de ver los temas y que permite modificar todos los aspectos de un sitio web de una forma mucho más clara para que no quede sin tratar ni el último píxel. Sin embargo, por el otro me da un poco de pena que WordPress termine de integrarse en este mundo de páginas web de temas genéricos y superlimpios donde todos los sitios web se ven iguales.

    En los últimos años, los temas por defecto se han caracterizado por un diseño más brutalista y tipografías más grandes. Aunque esto genera sitios webs más limpios donde solo hay una columna de texto sin distracciones a los lados, resulta un poco incómodo tener páginas web que griten tanto con esos tamaños de tipografía. Además, incluso en algunos casos considero que un aside en forma de barra lateral le puede dar un poco de personalidad a un blog pequeño e incluso un toque retro, ahora que está de moda que todos los sitios web se vean iguales.

    Hasta ahora he intentado usar los temas preinstalados de WordPress de forma intencional, para poder centrarme en el contenido, pero también intentar permitir que el sitio comunicase unas intenciones sin decir nada, simplemente a base de una combinación de colores o widgets de barra lateral. Sin embargo, continúo jugando en un entorno de pruebas para ver si puedo encontrar una combinación bonita pero que a la vez no le quite la personalidad a lo que hago.

  • Este post está escrito utilizando org2blog, un paquete para GNU Emacs que permite enviar buffers en formato Org a un sitio web de WordPress usando la API.

    Estoy probando GNU Emacs estos días otra vez. Ya lo probé hace un par de meses pero acabé dejándolo de usar. Realmente me sigue dando cierta curiosidad sana ver cómo son las cosas en Emacs.

    A pesar de que con los años en Vim se han incluido funciones como terminales en línea, y de que existen plugins para trabajar con Git desde hace bastante tiempo, en la práctica suelo encontrar tanta fricción que al final mi forma de trabajar suele ser tmux + vim dentro de un pane, para poder abrir panes auxiliares cuando necesito escribir comandos.

    Me da cierta curiosidad como en Emacs las cosas se integran de forma tan natural y cómo el sistema reacciona mejor a cosas como intentar leer el e-mail o documentos web desde dentro del editor de textos, y eso es lo que me ha llevado a volver a intentar probarlo, con un poco más de calma.

    Esta es la lista de cosas que me atraen de GNU Emacs:

    • Org-mode, aunque tengo que aprender a usar las funciones de lista de tareas, calendario, agenda, pomodoro… O sea, todo lo que no es escribir.
    • Org-babel, que permite hacer programación literaria. Por ejemplo, el archivo de configuración de mis dotfiles de Emacs es un archivo .org con bloques de código metidos entre prosa. Con un comando es posible extraer esos bloques de código y evaluarlos por separado.
    • Por alguna razón, los plugins para desarrollo de Ruby on Rails funcionan con menos fricciones que sus equivalentes para Vim.
    • Por alguna razón también, esta gente ha solucionado de una forma limpia el problema de los language servers, a diferencia del espectáculo que encuentro en Vim.
    • Repositorios de paquetes, que se integran en la aplicación (MELPA).
    • nyan-mode.

    Esta es la lista de cosas que me generan cierta incomodidad en GNU Emacs:

    • No es un editor modal.
    • Atajos crear una línea en blanco encima o debajo de la que estás, un poco complicado de simular pero lo conseguí.
    • Invitación a padecer túnel carpiano.

    Esta es una lista de cosas que me gustaría aprender a partir de aquí:

    • Elisp.
    • Leer e-mail.
    • Leer feeds RSS.
    • Lo de la org-agenda.
  • Retomo el tema importar entradas en WordPress de forma masiva.

    Recientemente volví a tirar de ese script para traerme un JSON con tweets viejos a danirod.es. Ni siquiera los he hecho públicos. Por el momento sólo los he hecho privados porque lo que me interesa es tenerlos consolidados. Tampoco son tweets recientes; estamos hablando de tweets que tienen más de una década. Todos los enlaces externos dan HTTP 404, están fatal escritos y, en general, es contenido poco interesante para internet. Pero me apetecía tenerlos a mano.

    Uso el plugin Syndication Links para conectar entradas que sean importadas de otras redes sociales con su URL de referencia; las sindicaciones de Hacker News son un ejemplo. En el caso de tweets de una cuenta que ya ni siquiera existe, es bastante irrelevante plantar un u-syndication. Aun así, me apetecía ponerlo.

    En el caso del plugin Syndication Links, la metadata sobre sindicación se guarda como un campo personalizado de WordPress llamado mf2_syndication. Con la API XML-RPC de WordPress es posible crear campos personalizados rellenando el array custom_fields. Hay que tener en cuenta que no es un clave-valor simple, sino que es un array de objetos, con su campo key para el título del campo, y su campo value para el valor del campo. En el módulo de npm, los campos se dan usando la key customFields en la llamada a newPost:

    client.newPost({
      title: '...',
      content: '...',
      customFields: [
        { key: 'field-1', value: 'value value' },
        { key: 'field-2', value: 'more value more value' }
      ]
    }, (e, id) => console.log(e, id));

  • A raíz del volcado de posts que cargué el otro día estoy considerando próximos datasets a importar. Exports procedentes de la GDPR, viejas entradas de blog sacadas de Wayback Archive, incluso tal vez puede que crosspost de cosas cargadas a YouTube o Twitter (algo que llevo años persiguiendo).

    Algunas consideraciones técnicas que he aprendido para la próxima:

    • Es mejor usar un entorno de staging mientras se hacen pruebas para no ensuciar el sitio web, porque lo más posible es que falle al principio.
    • Por lo tanto, es mejor ir de poco en poco, y no intentar importar un dataset muy grande hasta que no se ensaye con algo más pequeño que se pueda borrar fácilmente si se hace mal.
    • Por si hay que borrar, es mejor ponerles a los posts importados una etiqueta nueva para poder filtrar fácilmente posts con esa etiqueta y borrar todo. En mi caso, esa etiqueta ha sido hn-import.
    • Si el blog lo alojas por tu cuenta, no tienes que dar parte del API Rate Limit a nadie, pero corres el riesgo de causarte un ataque de denegación de servicio a ti mismo. Como casi hago, de hecho, porque mi código JavaScript intentó lanzar las 49 peticiones HTTP POST a la vez.
    • Por asociación de ideas, mejor apagar los hooks externos que se llaman al crear posts mientras se estén importando cosas. No pingbacks, no trackbacks, no webmentions, no ActivityPub. (Aparte que muchos de estos posts tienen unos cuantos años y no tiene mucho sentido generar notificaciones por esto.)
    • El feed RSS va a sufrir.

    El problema, como ya he dicho alguna vez, son los títulos. Muchas redes sociales no usan títulos en sus publicaciones, pero algo hay que poner para que la sindicación por RSS o al usar temas y widgets de WordPress que traten de mostrar el título de un post, tenga o no, puedan mostrar algo distinto a (sin título).

  • Una de las cosas bonitas de la GDPR es que casi obliga a las redes sociales y sitios similares a tener un sistema de exportado de datos. Y casi siempre lo hacen con algún formato estructurado como CSV, JSON o XML, fácil de procesar por un ordenador.

    Paralelamente, WordPress tiene el viejo confiable XML-RPC para crear posts de forma programática. Si no tienes mucha idea, recomiendan cerrar ese endpoint al exterior para evitar problemas. Pero en verdad, si sabes protegerlo, resulta muy práctico para crear posts a golpe de petición HTTP. (En teoría existe la API REST, pero bueno…)

    Con la ayuda de un cliente XML-RPC para WordPress que hay en NPM y de la API de Hacker News, hice en Node.js un script de un solo uso que crease una entrada por cada comentario y enlace enviado para enlazar hacia el comentario o la historia, siguiendo el modelo de sindicación PESOS de IndieWeb (Publish Elsewhere, Syndicate to Own Site). Le he puesto la etiqueta hn-import a la colección. ¿Cuál será el próximo archivo que importe?

    En sí la librería no es muy complicada de utilizar. Una vez tienes un cliente conectado es muy fácil chutarle un array de posts a crear (por ejemplo, procesar fila a fila un CSV o item a item un JSON o un XML). Primero se crea un cliente:

    const { createClient } = require("wordpress")
    
    const client = createClient({
      url: "https://example.com",
      username: "mi user",
      password: "mi password"
    })

    Luego definiendo el payload. Aquí es donde encuentro más cómodo crear un objeto JSON que declarar todo el chorizo XML de XML-RPC:

    const payload = {
      title: "El título de mi entrada",
      content: `
        <p>El contenido de mi entrada.</p>
        <blockquote>Aceptamos HTML.</blockquote>
        <p><a href="https://www.example.com">Y enlaces</a></p>
      `.trim(),
      status: 'publish', // podría ser 'draft' o 'private'
      termNames: {
        category: ['Categoría'],
        post_tag: ['tag 1', 'tag 2', 'tag 3'],
      },
      date: '2006-01-02 15:04:05',
      format: 'link' // podría ser 'aside', 'status', 'photo', ...
    }

    Y ya postear usando newPost. La librería es previa a promesas así que su único punto malo es que está orientada a callbacks.

    client.newPost(payload, (err, id) => {
      if (err) {
        console.error(err)
      } else {
        console.log(`ID del nuevo post: ${id}`)
      }
    })
  • Aprovechando que WordPress cumplió 18 años la semana pasada, me he decidido a instalar el clásico tema Default, el que fue el tema por defecto hasta la llegada de los temas “Twenty”.

    Por supuesto, Default no es un tema pensado para móviles. No tiene menús integrados (he tenido que traerme la navegación a la sección widgets). Sorprendentemente, se lleva bien con Gutenberg, aunque no tiene soporte para post formats por lo que no puedo marcar una entrada como “Minientrada”, ni como “Estado”, ni como ninguna de esas cosas que vinieron después, ya en la era Twenty, con temas compatibles con móvil, y con un diseño que roza lo brutalista, basado en colores fuertes, pocas decoraciones y tipografías grandes.

    Pongo esta captura de pantalla como evidencia por si en algún momento decido regresar a algo un poco más moderno.

  • La extensión Two Factor es un must. WordPress está detrás de ella y es open source, por lo que en principio debería estar libre de chantajes, modo PRO y demás cosas. Hace lo que tiene que hacer: te pide que introduzcas un código de 6 dígitos con una aplicación TOTP que estés utilizando.

    Two Factor te desactiva, desafortunadamente, el acceso XML-RPC y el WP-JSON. Hay quien tiene sus concerns y ve bien apagar esas APIs, pero por otra parte yo sí las quiero para poder automatizar cosas con WordPress. Esto lo tengo solucionado con dos cosas:

    • Con la extensión Application Passwords (que deja de ser necesario en WordPress 5.6 porque ya viene preinstalada), se pueden crear passwords especiales para poder crear integraciones con contraseñas aleatorias sin tener que darles nuestra propia contraseña.
    • Este snippet PHP para inhibir el Two Factor cuando se usa una Application Password. (De otro modo, las Application Password también tratarían de pedir un token 2FA, lo cual no es posible al automatizar.)

    Recomendaría también extensiones que prevengan ataques por fuerza bruta. La que yo uso inhibe el login si se introduce mal la contraseña varias veces, tanto por wp-login como por XML-RPC. Me quedaría conectarlo con el cortafuegos para bloquear directamente las IPs problemáticas, pero eso es un asunto para otro momento.

  • Probando a publicar desde la app de WordPress. Yo es que tampoco pido tanto ya. Algo que me deje publicar sobre la marcha sin fricción. No quiero commits de Git, no quiero contraseñas en un navegador ni tokens 2FA a cada vez que abra el panel. Quiero un botón en la hoja para compartir y con suerte integración con atajos de iOS. ?

  • Alguien se olvidó de su contraseña para entrar al panel de control del blog. Como por supuesto no tengo configurado el e-mail en este sitio web, hasta hoy no he tenido tiempo o voluntad de entrar en la base de datos y seguir el procedimiento de emergencia para recuperar la contraseña.

    Moraleja de la historia: si la contraseña no está en el KeePass (y sincronizada a al menos un dispositivo), la contraseña no existe.

  • De momento me está gustando el cambio del software de mi página web a WordPress. Puedo darle a lo de escribir todos los días un rato si me apetece sin encender mi ordenador, accediendo al wp-admin (el panel de control) directamente desde mi iPad.

    Cuando la semana pasada hice el reboot, tiré abajo todo el sitio web y levanté otro completamente en blanco. A primera vista parece que estoy aniquilando y eliminando de internet todo lo que he escrito en los últimos 6 años con el viejo software de mi web. Pero en realidad no. No me gusta el link rotting, y por supuesto en mi sitio web no se va a tolerar link rotting.

    Por eso cuando la semana pasada cambié el software de mi web pasé tanto tiempo configurando reglas en el proxy inverso que tiene la máquina que sirve www.danirod.es y otros 6 sitios web. (Se entiende ahora por qué a principios de año metí un Traefik para que me intentase echar una mano y no perder la cabeza.)

    Si sigues un enlace viejo a www.danirod.es, como el que puedes tener en marcadores desde ni se sabe cuánto, o el que puedes encontrar en algún tweet viejo, o en un buscador, ese enlace seguirá funcionando y enseñando contenido, incluso aunque haya sido barrido con el cambio de software. Haz la prueba, mira qué enlace tan sexy y numérico escrito en 2019 tengo por aquí: https://www.danirod.es/2019/084/1553504854.

    Un enlace a algo que haya publicado en esta página nunca puede dar HTTP 404. Si se ha escrito, tiene que estar. Como mucho, puede haber cambiado de dirección URL. De modo que si finalmente no “devuelvo” el nuevo software de mi web y sigo usando WordPress, una vez traiga el historial con todo lo que escribí en años anteriores, mantendré una tabla de traducción para que visitar el enlace que he pasado antes te mande a la nueva dirección del post.