<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Kevin Porras on Medium]]></title>
        <description><![CDATA[Stories by Kevin Porras on Medium]]></description>
        <link>https://medium.com/@kporras07?source=rss-7084522dac9f------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*vYNfISVGycdGOpOh.jpeg</url>
            <title>Stories by Kevin Porras on Medium</title>
            <link>https://medium.com/@kporras07?source=rss-7084522dac9f------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 31 May 2026 18:07:49 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@kporras07/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Automated Visual Regression Testing with Percy.io]]></title>
            <link>https://kporras07.medium.com/automated-visual-regression-testing-with-percy-io-c5439ac6bd40?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/c5439ac6bd40</guid>
            <category><![CDATA[testing]]></category>
            <category><![CDATA[automated-testing]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[drupal]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Tue, 15 Dec 2020 02:35:13 GMT</pubDate>
            <atom:updated>2021-01-09T02:06:38.288Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MrmUQB2Ze8yoMCWM2xVAyw.jpeg" /></figure><h3><em>Motivation</em></h3><p>Have you ever been in a situation where you have updated some components in your site and as an unintended effect you altered the look and feel of some other parts of your site and it went unnoticed for some time? If your answer is yes or you want to avoid it, then you’ll get great benefits of implementing visual regression testing for your site.</p><p>Visual regression is a technique used to compare a baseline set of approved screenshots to a newly taken set of screenshots in order to find differences that could introduce regressions in the styling of your site.</p><p>Percy.io is a visual review tool that helps you in this process of comparing screenshots. The tool will allow you to review the differences and mark them as approved or error depending on whether you actually want this change or not.</p><h3><em>Setting up our testing environment</em></h3><p>For this blog post, we’ll use a Drupal site hosted on Pantheon and the Continuous Integration is set up using CircleCI. The continuous integration is set up in 4 stages: build, deploy, deploy-test, deploy-live-hold and deploy-live. The deploy-live-hold stage has two jobs in it: a hold job for manual approval before live deployment and visual-regression. Assuming test and live will have the same database, the visual regression testing will compare (after deployment) a set of screenshots between those different environments.</p><p>You need to start by creating a percy.io account and create a new project within that account. Once done, look for the PERCY_TOKEN inside the project settings page. You’ll need this value later.</p><p>There are several ways to implement Percy in your project, we’ll follow what’s probably the most basic way to do it. We only need the percy CLI tool which is written in nodejs and some graphical UI stuff that it’s probably already installed in your computer.</p><p>To install the CLI you need to install the npm package as a local package by running:</p><p>npm install -D @percy/agent</p><p>Then, you need to create the test script. Save it into a file inside your repo. An initial example could be the following:</p><p>/**</p><p>* @file</p><p>* Percy snapshots.</p><p>*/</p><p>/* eslint-env node */</p><p>‘use strict’;</p><p>const PercyScript = require(‘@percy/script’);</p><p>PercyScript.run(async (page, percySnapshot) =&gt; {</p><p>await page.goto(process.env.BASE_URL);</p><p>await page.waitFor(‘#block-particle-content’);</p><p>await percySnapshot(‘homepage’);</p><p>await page.goto(process.env.BASE_URL + ‘/blogs’);</p><p>await page.waitFor(‘#block-particle-content’);</p><p>await percySnapshot(‘blog-listing’);</p><p>await page.goto(process.env.BASE_URL + ‘/projects’);</p><p>await page.waitFor(‘#block-particle-content’);</p><p>await percySnapshot(‘projects-listing’);</p><p>await page.goto(process.env.BASE_URL + ‘/contact’);</p><p>await page.waitFor(‘#block-particle-content’);</p><p>await percySnapshot(‘contact’);</p><p>await page.goto(process.env.BASE_URL + ‘/blog/preparing-your-site-drupal-9’);</p><p>await page.waitFor(‘#disqus_thread’);</p><p>await percySnapshot(‘blog-item’);</p><p>await page.goto(process.env.BASE_URL + ‘/projects/hipatia’);</p><p>await page.waitFor(‘#block-particle-content’);</p><p>await percySnapshot(‘project-item’);</p><p>});</p><p>In this example I’m using BASE_URL to get the site base url to start running the tests. To run the tests, you need to execute the following commands:</p><p>export BASE_URL=”<a href="https://kporras07.com">https://kporras07.com</a>&quot;</p><p>export PERCY_TOKEN=”token”</p><p>./node_modules/.bin/percy exec — node percy/snapshots.js</p><p>This will create the screenshots set in your percy account and will compare them to the last approved set of screenshots.</p><p>To automate this process, you could add it to your CI pipeline. If you do that, you need to first install some dependencies like this:</p><p>apt -y install nodejs gcc g++ make gconf-service libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libcairo2 libcups2 libdbus-1–3 libexpat1 libfontconfig1 libgcc1 libgconf-2–4 libgdk-pixbuf2.0–0 libglib2.0–0 libgtk-3–0 libnspr4 libpango-1.0–0 libpangocairo-1.0–0 libstdc++6 libx11–6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxss1 libxtst6 libappindicator1 libnss3 libasound2 libatk1.0–0 libc6 ca-certificates fonts-liberation lsb-release xdg-utils wget</p><p>The full section of CircleCI config file for this example looks like this:</p><p>visual-regression:</p><p>docker:</p><p>- image: kporras07/docker-drupal-nginx:php-7.4.x</p><p>working_directory: /var/www/kporras07</p><p>steps:</p><p>- attach_workspace:</p><p>at: /var/www</p><p>- run:</p><p>name: Run Snapshots</p><p>command: |</p><p>apt update -y</p><p>apt -y install nodejs gcc g++ make gconf-service libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libcairo2 libcups2 libdbus-1–3 libexpat1 libfontconfig1 libgcc1 libgconf-2–4 libgdk-pixbuf2.0–0 libglib2.0–0 libgtk-3–0 libnspr4 libpango-1.0–0 libpangocairo-1.0–0 libstdc++6 libx11–6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxss1 libxtst6 libappindicator1 libnss3 libasound2 libatk1.0–0 libc6 ca-certificates fonts-liberation lsb-release xdg-utils wget</p><p>export BASE_URL=”https://test-kporras07.pantheonsite.io&quot;</p><p>./node_modules/.bin/percy exec — node percy/snapshots.js</p><p>When a percy test is run, it should appear in your Percy UI and it will show you the build url. When you open that, it will look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*dzWgcy7BJQT8Ww-7" /></figure><h3><em>Conclusion</em></h3><p>Visual regression testing is an excellent choice to avoid visual regression errors and Percy.io is a good and easy to setup tool. Its free plan allows up to 5000 screenshots/month; so, it’s probably a good choice if your demand is not so high. It’s definitely a good tool to check out and you may want to give it a try.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c5439ac6bd40" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Trabajando independiente de forma legal desde Costa Rica]]></title>
            <link>https://kporras07.medium.com/trabajando-independiente-de-forma-legal-desde-costa-rica-e8ed501abd7c?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/e8ed501abd7c</guid>
            <category><![CDATA[costa-rica]]></category>
            <category><![CDATA[freelance]]></category>
            <category><![CDATA[freelancing]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Fri, 11 Sep 2020 02:46:51 GMT</pubDate>
            <atom:updated>2020-09-11T02:46:51.135Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_e9NCoMQPuxIYsXqylzvJw.jpeg" /><figcaption>Imagen tomada de Unsplash</figcaption></figure><p>Cuando hablamos de ser trabajador independiente nos referimos al hecho de no tener una relación laboral con el empleador sino de prestar servicios (profesionales) a otra persona o compañía. De esta forma el trabajador independiente (popularmente conocido como Freelancer) tiene la posibilidad de negociar su tarifa, organizar su propio horario y trabajar para las compañías que considere conveniente de acuerdo con sus propios parámetros.</p><p>Un tema aparte pero tristemente común es que en algunas empresas se ofrezca a los empleados trabajar bajo la modalidad de servicios profesionales pero aún con las condiciones de una relación laboral: horario, ubicación de trabajo, subordinación, etc. De hecho en tecnología es muy común y aunque no esté contemplado exactamente dentro de la legalidad, es algo que muchas veces se acepta bien sea por desconocimiento o por necesidad.</p><p>El objetivo de este artículo es ayudar a quienes inician como trabajadores independientes en Costa Rica y quieren hacerlo todo dentro del marco legal; para ello se explorarán posibles razones para optar por esta vía así como qué implica esto, algunos tips para organizarse de forma exitosa basado en mi propia experiencia y una reflexión final sobre el tema.</p><h3>¿Por qué ser trabajador independiente en Costa Rica?</h3><p>El expuesto anteriormente aunque no debería es a veces un motivo por el cual una persona opta por esta modalidad. Otras razones podrían ser porque ha decidido probar suerte a modo de emprendimiento unipersonal, también porque se quiere conformar una base de clientes con miras a un futuro emprendimiento. Otra razón que por ejemplo fue mi caso particular: una oportunidad de trabajo remoto con una empresa sin presencia en el país. Realizar dicho trabajo de esta manera permite que tanto la empresa no tenga que enredarse con la legislación costarricense ni usted como individuo tenga que complicarse con la legislación donde se ubica dicha empresa.</p><p>Sea cual sea el motivo por el que se desea ser trabajador independiente, es importante tener en cuenta qué implica realmente eso en Costa Rica si se desea hacer de manera legal y es lo que se abordará a continuación.</p><h3>¿Qué implica ser trabajador independiente en Costa Rica?</h3><p>Mi intención no es desalentar a nadie, simplemente mostrar la realidad tal cual es y esta es un poco compleja en Costa Rica; así que para abordarla la dividiré de la siguiente manera:</p><ul><li>Inicio de la actividad económica: los pasos que deben tomarse al iniciar la actividad generadora de ingresos.</li><li>Proceso permanente de la actividad económica: acciones que deben realizarse durante todo el tiempo que usted realice dicha actividad económica.</li></ul><h3>Inicio de la actividad económica</h3><p>Antes de iniciar la actividad económica, el trabajador independiente debe inscribirse como profesional liberal ante la Dirección General de Tributación de forma que pueda generar facturas por los servicios brindados. Además, debe inscribirse ante la Caja Costarricense de Seguro Social como Trabajador Independiente para cotizar ante la seguridad social.</p><h4>Inscripción ante Tributación</h4><p>Esto se realiza desde el portal de <a href="https://www.hacienda.go.cr/ATV/Seguridad/frmRegistroUsuario.aspx">ATV</a> a través de la Declaración de Inscripción ante el Registro Único Tributario. Para ello, debe seguir las instrucciones descritas en <a href="https://www.hacienda.go.cr/docs/5acd2da05585d_folleto%20modificacion%202018.pdf">este documento</a>.</p><h4>Inscripción como Trabajador Independiente ante la CCSS</h4><p>Estar afiliado como trabajador independiente ante la CCSS es un requisito legal de todo trabajador independiente en Costa Rica. Helen Bogantes realizó un <a href="https://helenbogantes.com/afiliacion-de-trabajador-independiente/">artículo muy completo al respecto</a>.</p><p>Mi experiencia en este proceso fue la siguiente:</p><ul><li>Retiré el formulario en físico en la sucursal</li><li>Llené el formulario en mi casa tomando en consideración ingresos y egresos</li><li>Esperé a tener mi primer factura</li><li>Fui a la oficina con los documentos requeridos</li></ul><p>Nota: en mi caso yo llevé el contrato por servicios profesionales que tenía, pero este estaba en inglés y me lo pidieron en español. Lo traduje yo mismo y llevé ambos y ya lo aceptaron.</p><p>Más información al respecto del proceso en la <a href="https://www.ccss.sa.cr/tramites?t=17">página oficial de la CCSS</a>. En la lista de <a href="https://www.ccss.sa.cr/faqs?cat=96">preguntas frecuentes</a> puede encontrarse los porcentajes de pago basados en los rangos de los ingresos de referencia (resultado de ingresos menos egresos).</p><h3>Durante la actividad económica</h3><p>Es necesario realizar factura electrónica para consignar los pagos. Si la empresa a la que se le trabaja tiene presencia en el país, le pedirán las facturas para justificar los gastos; sino la tiene, usted probablemente la necesite para justificar los movimientos de ingreso de dinero al país.</p><p>Para realizar las facturas, dependiendo del volumen de facturación que usted realice, puede utilizar la herramienta gratuita del Ministerio de Hacienda o alguna otra de su preferencia. Recuerde que algún cambio en este aspecto debe consignarse con una Declaración de Actualización del Registro Único Tributario.</p><p>Si su cliente está en Costa Rica, debe incluir el 13% del Impuesto sobre el Valor Agregado (IVA) salvo para las ventas incluidas como exenciones o no sujeciones explicadas en la ley de impuesto sobre la renta. Si por el contrario, usted está exportando servicios profesionales, de acuerdo con el artículo 8 de la Ley 9635, usted está exento de recaudar este tributo.</p><p>Además, mensualmente debe realizar la declaración del IVA; para ello debe rellenar el formulario D104–2 donde consigne las ventas y compras sujetas o no al IVA. Si el volumen de facturación es alto, es posible que se requiera apoyo de un contador para realizar dicha declaración.</p><p>Desde el tercer año que usted está inscrito en tributación debe realizar pagos parciales de renta cada trimestre. Esto se calcula con base en las declaraciones de renta de los dos años anteriores. El pago se puede realizar a través de las plataformas del banco (al igual que los pagos del IVA).</p><p>Recuerde pagar la seguridad social cada mes. De no hacerlo, tendrá que pagar recargos por mora y después de 59 días de no pago entrará a cobro judicial. Este pago también puede realizarse desde las plataformas en línea de los bancos.</p><p>Al finalizar cada año fiscal debe realizarse la declaración de renta y la declaración informativa de resumen de clientes y proveedores. El final del año fiscal anteriormente era en septiembre; a partir de este año es en diciembre, por lo que este año, el año fiscal es de 15 meses. La declaración informativa (D151) se realiza a través del programa Declara7 y es un poco complejo de instalar (obviamente sólo sirve en Windows); así que tome en cuenta el tiempo que esto va a tomarle. La declaración de renta (D101) se realiza a través del portal ATV. En esta se consigna el monto total de salarios recibidos (casilla 46 bis), el monto total de las facturas realizadas y el monto total de gastos deducibles (si no tiene facturas, este puede ser de hasta un 25% del ingreso bruto). Helen Bogantes también tiene un <a href="https://helenbogantes.com/declaracion-d101/">artículo muy bueno al respecto</a>.</p><p>Es decisión de cada persona si maneja la contabilidad por sí mismo o si requiere los servicios de un contador; para ello, debe considerar el volumen de transacciones que se realizarán a lo largo del año, la complejidad de las mismas y si quiere dedicar el tiempo necesario para realizar todos los trámites que esto involucra.</p><h3>Tips para organizarse como profesional independiente</h3><p>Basado en mi experiencia, la siguiente es una lista de mis recomendaciones al empezar a ser profesional independiente.</p><h3>Realizar una estimación de los ingresos anuales por facturas</h3><p>Esto permitirá realizar una estimación del impuesto sobre la renta y permitir establecer un porcentaje de ahorro por concepto de este impuesto, de forma tal que al llegar el momento de pagar no se tenga que “correr” a buscar el dinero.</p><h3>Realizar una estimación de los ingresos anuales por salarios</h3><p>Si recibe (o recibió) salarios, realizar una estimación de los mismos le permitirá tomar esto en cuenta a la hora de estimar el porcentaje de impuesto sobre la renta.</p><h3>Realizar ahorros para aguinaldo y vacaciones</h3><p>Si por su relación laboral no recibe ingresos por concepto de aguinaldo y vacaciones, debería realizar un ahorro para pagarse estos rubros y poder disfrutarlos sin afectar su flujo de ingresos habituales.</p><h3>Otros tips</h3><p>Es común que al trabajar con facturas, estas no se paguen inmediatamente sino en un tiempo establecido usualmente por quien recibe el servicio. Esto comúnmente se conoce como <a href="https://en.wikipedia.org/wiki/Net_D">NET D</a> y puede ser NET10, NET15, NET30 o NET60; siendo el número la cantidad de días que pasarán desde el momento en que se realiza la facturación y el momento en que se debe esperar recibir el dinero. Es importante tener estos términos claros al momento de iniciar para poder planificar la transición si se está pasando de asalariado a solamente trabajador independiente.</p><h3>Template de Spreadsheet</h3><p>Para poder realizar este cambio, realicé un spreadsheet que me ha ayudado a organizarme. Una versión de este que puede servir como template para su propio spreadsheet la puede encontrar en <a href="https://docs.google.com/spreadsheets/d/1qRfWKW8KgK1KEuBMgofmZS7uRGpHORwB8tbsWkx3ra0/edit?usp=sharing">este enlace</a>.</p><h3>Conclusiones</h3><p>El cambio de asalariado a trabajador independiente puede ser complicado al inicio, pero si se hace por una buena oportunidad y económicamente vale la pena, es una muy buena opción a considerar; sin embargo, se debe ser bastante organizado para no morir en el intento.</p><p>Si después de leer este artículo tenés alguna duda, será un gusto tratar de ayudarte :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e8ed501abd7c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Preparing your site for Drupal 9]]></title>
            <link>https://kporras07.medium.com/preparing-your-site-for-drupal-9-31bb173220fb?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/31bb173220fb</guid>
            <category><![CDATA[drupal-9]]></category>
            <category><![CDATA[drupal]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Sat, 11 Jul 2020 03:22:53 GMT</pubDate>
            <atom:updated>2020-07-11T03:22:53.529Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*w_apgxHm2eA8FjHbCE-jdQ.jpeg" /><figcaption>Image taken from Unsplash</figcaption></figure><p><strong>Motivation</strong></p><p>Drupal 9 was released on June 3rd and it’s the greatest Drupal release ever and still the easiest to upgrade to if your site is up-to-date in the latest 8.x version.</p><p>Drupal 9.0 doesn’t really include any new feature in comparison with 8.9; however, this is part of the greatness of the version because no new features mean no new unknown bugs. The only differences from 8.9 to 9.0 is that 9.0 removes all the backwards compatibility layer for all of the stuff that has been deprecated during the whole lifecycle of Drupal 8 so that we can keep the drop always moving to bring new great features in the upcoming releases. Also, Drupal 9 includes upgrades for several dependencies included in core with Symfony (3 =&gt; 4.4) and Twig (1 =&gt; 2) among the most important ones.</p><p>The release cycle will keep being the one we already saw for Drupal 8: one minor release each 6 months. This enables in Drupal the possibility of adding new big features frequently so, you definitely should upgrade to Drupal 9 soon even if Drupal 8 support will still be available until November, 2021.</p><p>So, with all this in mind, how could I upgrade my site to Drupal 9? Keep reading…</p><h3>How to upgrade to Drupal 9</h3><p>The very first step you should take to upgrade your site to Drupal 9 is to upgrade Drupal core to the latest Drupal 8 version (i.e. 8.9) and to upgrade all of your contrib projects to their latest version compatible with Drupal 8. Keep in mind that <a href="https://www.drupal.org/node/3108648">Drupal now supports semantic versioning</a> so you’re not really only looking for 8.x versions for your contrib projects.</p><p>Once you have everything up-to-date, you need to install <a href="https://www.drupal.org/project/upgrade_status/">Upgrade Status</a> module in order to get a report about your Drupal 9 compatibility. When you install this module, you’ll get a new menu entry located at /admin/reports/upgrade-status. In this page, you’ll have a list of all the modules and themes installed on your site and you can scan them looking for potential issues about Drupal 9 compatibility. This scan could happen either through the UI or through drush command (drush us-a project). In my experience, big modules won’t play well with UI soI had to run a couple of modules through drush command.</p><p>I recommend you to scan to all of the projects in one of the big groups (custom or contrib) at once and then start working on the fixes. For the purpose of this article, I’ll assume you’ll scan initially all your contrib projects. Once you run this analysis, you can have the following situations:</p><h3>All of your contrib projects are ready for Drupal 9</h3><p>If this is your situation, be happy. You have nothing to do on contrib land. Move to custom modules.</p><h3>Some of your contrib projects aren’t ready for Drupal 9 yet</h3><p>If this is your situation, Upgrade Status will report what are the missing changes needed for these projects. The first thing you need to do is to go to the project page. There you’ll find what are the expectations for this project releases respect Drupal 9 compatibility. Possible scenarios are:</p><ul><li>There will be Drupal 9 support in current major branch</li><li>There will be Drupal 9 support in another major branch</li></ul><p>If there will be support in next major branch (see screenshot), you need to ensure that (if needed) there will be a upgrade path. You can find this either in the project page or in the issue queue.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*dxGB5moCL6Oqnpt0" /></figure><p>If there is support in next major branch and there’s already a release, you should try installing it in your site to know if it fixes the issues you found. Every time you install a new version, you need to run database updates and re-run the Upgrade Status scan.</p><p>If either you didn’t find support for next major branch or you updated and you still find incompatibilities, it’s your time to start searching in the issue queue. It’s highly probable that there’s already an issue trying to land Drupal 9 compatibility in this project. You can read the comments and test the patches if needed. Remember that patches are created against project’s dev branch so they may not apply to your current version and you may need to switch to dev version. Be kind and leave a comment in the issue queue when you test a patch so that people can know whether it worked or not for you (again, once added a patch, run db updates if needed and re-run Upgrade Status). If you tested a patch that was in Needs Review status and nobody has previously tested and it worked for you, feel free to mark it as RTBC (Reviewed and Tested By the Community) so that maintainers know it’s working.</p><p>If you tested one patch and it worked on the dev version of the project but it doesn’t apply on the version you had in your site, it’s up to you if you want to switch to the dev version or to wait for next release. It’s also sometimes useful to ask the maintainers to release a new version so that people can use the projects in a more stable way.</p><p>If there was no patch or the patches don’t work to make the project compatible with Drupal 9, you may also help to make it compatible. You can follow <a href="https://www.drupal.org/contribute/development">Drupal contribution guidelines</a> to help to this project. Maybe it’s also time for you to take a look at the great <a href="https://www.drupal.org/project/rector">Rector</a> project to automate some of the work required for compatibility. If you contribute a patch, don’t forget to set issue status to Needs Review so that other people can help to review the patch and hopefully land it in the project.</p><p>Your objective in this contrib projects stage is to have all of your projects compatible with Drupal 9. Once done this (or in parallel, it’s totally up to you) you can move to your custom modules and themes.</p><p>For your custom projects, you can also use Rector to help with some of the work needed and you can follow the instructions given by Upgrade Status to upgrade your modules. If you need some help to know how to make the changes, the <a href="https://www.drupal.org/list-changes/drupal">Change Records</a> is an excellent resource to start looking for help.</p><p>Let’s assume all of your contrib and custom projects are now Drupal 9 compatible according to Upgrade Status. This module also gives you information about the PHP and MySQL versions needed so, you need to ensure you meet these requirements on your hosting platforms:</p><ul><li>If webserver is Apache, it should be 2.4.7 or superior.</li><li>PHP 7.3 or higher</li><li>MySQL or Percona &gt;= 5.7.8 or MariaDB &gt;= 10.3.7</li></ul><p>One more thing to check is Drush: even though the only Drush version supported on Drupal 8 since 8.4 is Drush 9; you may still have Drush 8. Drush 8 is not compatible with Drupal 9 so you need to upgrade to Drush 10 to take advantage of latest features on Drush.</p><p>Once everything is done, it’s your time to let the magic happen. Follow the instructions in the <a href="https://www.drupal.org/docs/upgrading-drupal/upgrading-from-drupal-8-to-drupal-9-or-higher#s-upgrading-a-composer-based-drupal-8-site">official documentation</a> to do the packages update with composer.</p><h3>Summary and Conclusion</h3><p>It may sound like a lot of work, but in reality it’s all about ensuring your site doesn’t contain deprecated code that won’t work with Drupal 9. You don’t need to run to do the upgrade if your site is complex, but it’s highly recommended you start thinking on doing it to keep taking advantage of the new features that will be included in Drupal 9.1 (to be released in December, 2020) and following minor upgrades. So, if you have some time, this is a good time to start thinking in your site upgrade to Drupal 9.</p><p>Feel free to leave any suggestions or questions in the comments section.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=31bb173220fb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating Drush commands inside a theme]]></title>
            <link>https://kporras07.medium.com/creating-drush-commands-inside-a-theme-eb63497bc794?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/eb63497bc794</guid>
            <category><![CDATA[drupal-development]]></category>
            <category><![CDATA[drush]]></category>
            <category><![CDATA[drupal-8]]></category>
            <category><![CDATA[drupal]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Wed, 17 Jun 2020 01:08:32 GMT</pubDate>
            <atom:updated>2020-06-17T01:08:32.786Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hp3zkJNHrY9RjWrBo75-WA.jpeg" /><figcaption>Image taken from <a href="https://unsplash.com/photos/ZKbg9T85N4U">Unsplash</a></figcaption></figure><p>One of the greatest things of Drupal is Drush, the command line tool that was created to administer (and develop) Drupal. Out of the box Drush allows you to run a big number of commands to administer your site, from rebuilding caches to generating one time login link and a lot of other stuff.</p><p>Something great about Drush is that you can easily provide commands in your module and it even has a generator to scaffold the code you’ll need for your command. You can find more information on how to write a Drush command inside a module in the <a href="https://docs.drush.org/en/master/commands/">official documentation</a>. In summary, for Drush &gt;= 9, you need to do:</p><ul><li>Add a couple of lines to composer.json</li><li>Add a drush.services.yml file to provide the services that will bring your commands to life</li><li>Create the commands file</li></ul><p>If you do that as expected, your command will be auto-discovered (if the module is enabled) and you’ll be able to use it once you rebuild caches.</p><p>However, the above method doesn’t work for disabled modules or for themes (no matter whether they’re enabled or not) because Drush only do auto-discover of commands inside enabled modules. So, if you need to add a command to a theme, you need to do things a little bit different. The following is a list of the key differences.</p><h3>Dependency injection is not available</h3><p>You can’t rely on Drupal to inject the dependencies you declare in the drush.services.yml file so, you can’t receive them in the constructor of your class. Instead of that, you need to rely on \Drupal::service() function and be sure that you specify @bootstrap full if you need to use dependencies from the services container.</p><h3>Autoload should be declared in composer.json</h3><p>You need to explicitly declare autoload configuration in the composer.json file so that Drush knows how to discover your classes. Add the following snippet to your composer.json (and update as needed):</p><pre>&quot;autoload&quot;: {</pre><pre>    &quot;psr-4&quot;: {</pre><pre>        &quot;Drush\\Commands\\my_theme\\&quot;: &quot;Commands/my_theme/&quot;</pre><pre>    }</pre><pre>},</pre><h3>Adapt the path and namespace of your commands file</h3><p>Following the above example (and assuming your theme is named my_theme), you need to place your command file inside Commands\my_theme folder (do not use src folder). Also, the namespace for your class should be Drush\Commands\my_theme so that Drush can discover it.</p><h3>Invoke the command using the theme path</h3><p>Final difference is that you need to invoke your command using the path to the theme so that Drush knows where to find the command (remember that it’s not auto-discovered). So, following the above example, you need to run your command like this: drush — include=docroot/themes/custom/my_theme mycommand</p><p>Creating commands inside Drupal themes is not so frequent in comparison to create them inside Drupal modules, but sometimes you may need to do it (e.g. to publish a contrib theme) so it’s useful to know the key differences to do it properly so that Drush can invoke your command.</p><p>I hope this has been useful for you :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=eb63497bc794" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Drupal 9 Porting Weekend]]></title>
            <link>https://kporras07.medium.com/drupal-9-porting-weekend-2c7a3d7da5b7?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/2c7a3d7da5b7</guid>
            <category><![CDATA[drupal-8]]></category>
            <category><![CDATA[contribution]]></category>
            <category><![CDATA[drupal]]></category>
            <category><![CDATA[drupal-9]]></category>
            <category><![CDATA[community]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Wed, 27 May 2020 01:59:14 GMT</pubDate>
            <atom:updated>2020-05-27T02:00:13.406Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KudAKcCeTVB7RfImI5Pocg.jpeg" /><figcaption><em>(Photo credit: </em><a href="https://www.flickr.com/photos/pepej/10113511095"><em>Josef Jerabak</em></a><em>.)</em></figcaption></figure><p>Last weekend global Drupal community celebrated <a href="https://groups.drupal.org/node/535946">Drupal 9 Porting Weekend</a> to speed up contrib modules to get a Drupal 9 compatible release. The date was chosen in honour of the cancelled DrupalCon Minneapolis.</p><p>I have worked with open source since I was in college so I am always motivated to contribute back to the community. I have been using Drupal for 7 years and although I’m not the most active member of the community, I like to give back each time I can. Besides that, the company I’m currently working for encouraged me to participate on this event so I was doubled motivated.</p><p>I joined for 2.5 hours on saturday and during this time I was able to review and create some patches. I worked on 12 different issues between patches, reviews and comments so I ended my contribution day highly motivated and really happy to be part of this great Drupal community.</p><p>At the time of writing this article there are more than 500 issues with the event official tag: “Drupal 9 porting weekend”. That’s a huge amount of issues for a weekend so I’d say this event was a great success. Thanks to the whole community for making it possible and special thanks to the mentors and organizers who made it possible.</p><p>To end this article I would like to encourage you to give back to the open source projects you use the most. It could be through code, documentation or any other mean you are capable to contribute. And if you work with Drupal, you are more than welcome to get a <a href="https://www.drupal.org/association/individual-membership">Drupal Association Membership</a> to give back economically to the project.</p><p><em>Article originally published at </em><a href="https://kporras07.com/blog/drupal-9-porting-weekend"><em>https://kporras07.com/blog/drupal-9-porting-weekend</em></a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2c7a3d7da5b7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A propósito de la actualidad nacional]]></title>
            <link>https://kporras07.medium.com/a-prop%C3%B3sito-de-la-actualidad-nacional-3bc667448826?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/3bc667448826</guid>
            <category><![CDATA[costa-rica]]></category>
            <category><![CDATA[abortion]]></category>
            <category><![CDATA[public-health]]></category>
            <category><![CDATA[law]]></category>
            <category><![CDATA[spanish]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Sat, 14 Dec 2019 23:58:22 GMT</pubDate>
            <atom:updated>2019-12-14T23:58:22.282Z</atom:updated>
            <content:encoded><![CDATA[<h4>Aborto terapéutico, norma técnica y otras desinformaciones</h4><p>Tengo demasiado tiempo de no escribir por aquí e igualmente demasiado tiempo de esforzarme por mantenerme callado ante tanto que pasa en el país y en particular ante el llamado aborto terapéutico.</p><p>El Código Penal de Costa Rica declara impune desde hace muchos años el aborto bajo unas condiciones explícitamente dadas (que se atente contra la vida y la salud de la mujer); esto tiene más de 40 años de ser así y la norma técnica no viene a cambiar NADA de eso, viene a REGULARLO.</p><p>Inserto aquí algunos disclaimers:</p><ul><li>Leí la norma desde mi humilde entendimiento</li><li>Soy católico y no estoy a favor del aborto (por favor no deje de leer sea cual sea su posición), incluso he participado en una marcha por la vida y la familia hace muchos años cuando no estaba tan polarizado todo.</li><li>No voy a decir que la norma es perfecta o imperfecta, eso le tocará a los profesionales en medicina y supongo que derecho.</li></ul><p>Dicho lo anterior, repasemos la norma rápidamente:</p><ul><li>Si la mujer considera su vida o salud en peligro, puede solicitar estudiar su caso para practicar un aborto. Un médico también puede realizar esta solicitud.</li><li>Varios médicos y otros profesionales deben evaluar la situación.</li><li>Si la respuesta es que se recomienda un aborto, se pide la autorización explícita de la mujer; si ella no la da se acabó el tema.</li><li>Si la respuesta es negativa, la mujer podría solicitar que se reevalúe UNA vez más.</li></ul><p>(Disculpas si mi resumen es corto o incompleto, no tengo la norma a mano mientras escribo, pero usted puede buscarla fácilmente y leerla, son alrededor de 12 páginas)</p><p>Entonces: <strong>no se está agregando nuevos casos donde se permita el aborto, no se está expandiendo de forma alguna el artículo del código penal, no se está permitiendo el aborto libre; simplemente se está normando algo que ya existía.</strong></p><p>El principal cuestionamiento que he leído hacia la norma: que abre portillos para el aborto libre. Eso no lo tengo yo claro, pero en todo caso, no creo que sea la norma quién los abra sino el mismo artículo que tiene más de 40 años de existir. Entonces no logro entender por qué sigue el pleito al respecto y algunas “figuras públicas” haciendo polémica al respecto del tema, preguntas súper sesgadas y dividiendo aún más al país (mentiras, sí entiendo, campaña electoral permanente se llama 😡)</p><p>Hoy leí un <a href="https://facebook.com/story.php?story_fbid=948818605511677&amp;id=522439464816262">comentario de Padre Sejo</a> que me parece que resume perfectamente la posición de la Iglesia al respecto y lo que a mí me parecería lo ideal en cuanto a este tema tan polémico; pero insisto en el hilo central de este artículo: <strong>la norma técnica no viene a inventar el agua tibia, solo a reglamentar lo ya existente.</strong> Sencillo. Fin del tema.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3bc667448826" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cinco]]></title>
            <link>https://kporras07.medium.com/cinco-640ecb74aca2?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/640ecb74aca2</guid>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Tue, 04 Jun 2019 04:26:32 GMT</pubDate>
            <atom:updated>2019-06-04T04:26:32.519Z</atom:updated>
            <content:encoded><![CDATA[<h4>Feliz cumpleaños número 5 de la segunda ronda</h4><p>Hoy hace cinco años, a tan solo 50 metros de mi lugar de trabajo recibí aquella llamada que me daba la terrible noticia: su corazón había dejado de latir, no iba a volver a escuchar su risa, no iba a volver a escuchar su voz, no iba a volver a sentir su abrazo.</p><p>Esa llamada sin lugar a dudas marcó un antes y un después en mi vida; los recuerdos del qué pasó después se confunden en mi mente, sólo queda claro el dolor inmenso que se apoderó de mí justo en el momento de escucharlo.</p><p>Muchos recuerdos se cruzan por mi mente cada vez que le recuerdo, muchos pensamientos asociados a esas últimas dos semanas en que corpóreamente estaba entre nosotros; hasta un poco de resentimiento conmigo mismo que costó sanar. Pero hoy comprendí que sin yo saberlo se despidió de mí, siempre con su alegría, probablemente la forma en que quería que le recordara y así lo haré por siempre.</p><p>Muchos regalos intangibles recibí de su persona, entre ellos conocer su humanidad y por supuesto &quot;Les Luthiers&quot;. Las veces que he tenido la oportunidad de verlos en vivo estoy seguro de que su presencia me ha acompañado.</p><p>Hoy sólo me queda dar gracias a mi Dios por haberme regalado el don de compartir su vida, su humanidad, su alegría y por permitirme recordarlo así siempre que viene a mi mente.</p><p>Anoche me fue dado un regalo inesperado. Soñé con vos. Tenía mucho tiempo de no verte y tenía miedo de estar olvidando tu rostro, pero no, ahí estabas y te veías tan alegre y tierno como siempre fuiste.</p><p>No, en realidad no eras vos, pero se veía exactamente igual a vos y sabía de tu existencia e intentaba consolarme. Su rostro, su ternura, su sabiduría, su cariño, todo era idéntico a vos. Me faltó abrazarle, pero ese rato minúsculo que duró el sueño me hizo enormemente feliz.</p><p>No te olvides del camino, volvé a mis sueños más a menudo por favor :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=640ecb74aca2" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[5 de octubre, 2014]]></title>
            <link>https://kporras07.medium.com/5-de-octubre-2014-cc41f3dc8f64?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/cc41f3dc8f64</guid>
            <category><![CDATA[writing-prompts]]></category>
            <category><![CDATA[spanish]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Wed, 09 Jan 2019 04:29:46 GMT</pubDate>
            <atom:updated>2019-01-09T04:29:46.498Z</atom:updated>
            <content:encoded><![CDATA[<p>Era primer domingo de mes, día en que usualmente la familia salía de paseo, pero él había decidido no ir ese día, en parte porque odiaba esos paseos y ya había agotado su cuota de salidas familiares con el cumpleaños número siete de su hermana menor y en parte porque debía dejar de posponer aquello que hace tanto retrasaba.</p><p>Al ser las diez de la mañana quedó sólo en casa y decidió empezar por ordenar su cuarto y por supuesto para lograrlo tuvo que poner música, entonces busco entre la colección de discos que tenían en su casa y escogió uno que decía tener 112 canciones pues ese de fijo le iba a alcanzar.</p><p>A la una de la tarde estaba terminando su labor y buscó qué comer. Era la 1:30 p.m., ya había terminado y seguía solo en casa. Cómo su madre cumpliría años al día siguiente, decidió ordenar también su cuarto como sorpresa de cumpleaños.</p><p>Empezó por sacar toda la ropa del ropero y allí al fondo encontró una libreta rosada que parecía tener unos diez años enterrada ahí. Movido por la curiosidad la abrió en la última página y no vio nada más que una letra desconocida que escribía una fecha y un número: 112. Se preguntaba que podía ser aquello. Continuó urgando en la libreta pero no encontró nada más interesante, así que la dejó en su lugar y siguió con su trabajo.</p><p>Aquella libreta no salía de su mente, de hecho fue a buscarla de nuevo y ahora vio un detalle que había pasado por alto: la libreta tenía un calendario del año 2006 y un círculo en rojo alrededor del primero de diciembre. Extrañado por la sucesión de coincidencias, decidió irse directamente a la última canción del disco y se encontró con que era de Lorenzo Antonio. Las dudas iban creciendo en su interior pero aún no lograba fabricar ninguna historia que tuviera sentido.</p><p>Decidió continuar con lo que estaba haciendo y en una de las gavetas encontró unos pétalos de rosa terriblemente marchitos que al parecer su madre guardaba quién sabe por qué. Su sorpresa fue aún mayor cuando en la última gaveta encontró un sobre azul que dentro contenía un fragmento de algo que parecía haber sido una carta en la que habían palabras muy borrosas y unas partes perdidas. De lo que estaba allí logró entender algo como esto:</p><p>&quot;__ diciembre de 20</p><p>Sofía gracias por este tiempo maravilloso (pedazo faltante)</p><p>Estos días ___________________ mejor _______ (pedazo faltante)</p><p>Desde ahora, Isla _________ será nue...(pedazo faltante)</p><p>Tuyo por siempre,</p><p>(pedazo intencionalmente rasgado)&quot;</p><p>En ese momento, muchas cosas se rompieron en su vida y no sabía si tendría el valor de hablarlo con su madre.</p><p>Cuando su familia llegó, Sofía traía feliz una rosa que su marido le había regalado en el viaje; al ingresar a la casa, accidentalmente la golpeó con algo y un pétalo cayó de ella; el joven lo tomó y caminó hacia donde estaba su madre y le dijo mostrándole el pétalo caído: &quot;Mamá tenemos que hablar&quot;. En ese instante, la sonrisa se borró del rostro de ella y todas las dudas desaparecieron de la mente de él y lo terminó de embargar un sentimiento que no sabía cómo describir.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=cc41f3dc8f64" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[El último momento de la infancia]]></title>
            <link>https://kporras07.medium.com/el-%C3%BAltimo-momento-de-la-infancia-77bdaf487d58?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/77bdaf487d58</guid>
            <category><![CDATA[spanish]]></category>
            <category><![CDATA[halloween]]></category>
            <category><![CDATA[writing-prompts]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Sat, 05 Jan 2019 04:14:30 GMT</pubDate>
            <atom:updated>2019-01-05T04:14:30.679Z</atom:updated>
            <content:encoded><![CDATA[<p>Aquel martes 31 de octubre como era costumbre saldría con sus primos y hermanos a pedir dulces por el barrio, y al terminar en su casa le esperarían con comida, queque y regalos; pero este año tenía un matiz especial: cumplía trece y sería oficialmente adolescente; aquello sin lugar a dudas le llenaba de ilusión.</p><p>Desde las diez de la mañana esperaba ansiosamente la hora de salir a pedir dulces; sabía que era su último Halloween como niña y tenía que disfrutarlo al máximo pero el tiempo parecía no querer avanzar como normalmente lo hacía y la expectativa crecía cada minuto.</p><p>Finalmente el reloj marcó las seis de la tarde; Juan y María (sus hermanos menores) también estaban listos y pasaron por casa de sus primos para ir juntos como lo habían hecho desde hace cinco años cuando María apenas era una bebé de casi un año.</p><p>El tiempo pasó volando y no fue sino hasta las 8:30 pm que se percataron de la hora y decidieron volver a casa. A tres cuadras de su hogar lograron divisar al final de la calle una sirena y un grupo de gente: algún gracioso habrá reventado un panal, pensaron; y siguieron su camino sin mayor prisa. Al estar más cerca, su sorpresa fue que la sirena era en su casa y que lo que era su casa ya no estaba allí y en su lugar solo habían restos de la estructura y muchas cenizas: la plancha con la que había desarrugado su ropa había quedado conectada y en resultado saltaba a la vista.</p><p>María y Juan no comprendían aquella escena pero ella ahora estaba completamente segura de que una nueva etapa iniciaba en su vida.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=77bdaf487d58" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Yo sólo comparto]]></title>
            <link>https://kporras07.medium.com/yo-s%C3%B3lo-comparto-5e6b60631f62?source=rss-7084522dac9f------2</link>
            <guid isPermaLink="false">https://medium.com/p/5e6b60631f62</guid>
            <category><![CDATA[spanish]]></category>
            <category><![CDATA[fact-checking]]></category>
            <category><![CDATA[fake-news]]></category>
            <dc:creator><![CDATA[Kevin Porras]]></dc:creator>
            <pubDate>Fri, 04 Jan 2019 02:35:33 GMT</pubDate>
            <atom:updated>2019-01-04T02:43:45.584Z</atom:updated>
            <content:encoded><![CDATA[<p>En la era de las redes sociales en que vivimos, mucha gente no se ha dado cuenta del enorme poder que tiene en sus manos con cada comentario, cada reenviar o cada compartir.</p><p>En el mundo digamos &quot;real&quot; (las redes sociales también son mundo real), si alguien anda contando cosas a &quot;todo el mundo&quot; o si anda difundiendo información falsa o inexacta es tachado de chismoso; pero parece ser que en el mundo de internet no funciona así.</p><p>Es muy pero muy común ver gente que comparte cualquier imagen o cualquier información por el solo hecho de que alimenta una posición con la que está a favor sin siquiera tomarse la molestia de en cinco segundos verificar qué tan cierta es esa información y si alguien le hace ver que no es cierto se escudan en el &quot;yo sólo comparto&quot; o peor aún &quot;es que uno nunca sabe&quot;. Algo que podría parecer tan inofensivo como el hecho de compartir algo sin verificarlo podría estar contribuyendo a la división del país, a aumentar odios, a difamar y dañar a una persona, a tantas cosas que estoy seguro que si se detienen a pensarlo aunque sea por un instante no les gustaría hacer; y entonces, ¿por qué seguimos compartiendo cuánta cosa nos aparezca sin hacer el más mínimo esfuerzo por indagar?</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*7anYqwHdhQaDLj-Lv_oYUQ.png" /></figure><p>Esta imagen es una mini guía de cómo verificar una información antes de compartirla; por favor, guárdela en favoritos, marcadores, galería, donde quiera; pero póngala en práctica para ayudar a construir una mejor sociedad digital y de paso una mejor sociedad en general.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5e6b60631f62" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>