<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rossella Ferrandino</title>
    <description>The latest articles on DEV Community by Rossella Ferrandino (@rossellafer).</description>
    <link>https://dev.to/rossellafer</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F407325%2F5b95c78d-9d1b-46b3-9caf-9726abad7e6f.jpg</url>
      <title>DEV Community: Rossella Ferrandino</title>
      <link>https://dev.to/rossellafer</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rossellafer"/>
    <language>en</language>
    <item>
      <title>Beyond keywords: technical SEO wins for developer portfolios</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Sat, 15 Feb 2025 09:13:22 +0000</pubDate>
      <link>https://dev.to/rossellafer/beyond-keywords-technical-seo-wins-for-developer-portfolios-4ko8</link>
      <guid>https://dev.to/rossellafer/beyond-keywords-technical-seo-wins-for-developer-portfolios-4ko8</guid>
      <description>&lt;p&gt;Back in 2020, I wrote an &lt;a href="https://dev.to/rossellafer/seo-tips-for-your-developer-portfolio-26fm"&gt;article about improving the SEO score for your developer portfolio&lt;/a&gt;. It resonated with many, sparking discussions among fellow developers on how to improve their portfolio’s visibility and technical SEO. However, the SEO landscape has evolved since then, and there are even more opportunities to enhance performance beyond just optimizing meta tags and keywords.&lt;/p&gt;

&lt;p&gt;In this article, I'll cover some of my learnings on this topic, focusing on technical SEO improvements that not only boost your portfolio’s visibility in search engines but also enhance its overall user experience. My portfolio follows a simple structure, using only HTML, CSS, and JavaScript, but these optimizations can be applied to more complex setups as well—keeping in mind that heavily &lt;a href="https://www.aeripret.com/content-rehydration/" rel="noopener noreferrer"&gt;hydrated JavaScript&lt;/a&gt; can pose SEO challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structured Data: helping search engines understand your portfolio
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How to implement Schema Markup for your portfolio
&lt;/h3&gt;

&lt;p&gt;Structured data (JSON-LD) helps search engines better understand the content on your site. By implementing schema markup, you can improve the way your portfolio appears in search results with rich snippets, making it more attractive to potential employers and recruiters. I’ve seen this strategy used effectively in e-commerce websites, where product, collection, and Local Business schemas enhance visibility in search results. For developer portfolios, I am currently testing it out to see if it makes a measurable difference. If you're interested in learning more, you can explore the official documentation at &lt;a href="https://schema.org/" rel="noopener noreferrer"&gt;Schema.org&lt;/a&gt; and check out their &lt;a href="https://github.com/schemaorg/schemaorg" rel="noopener noreferrer"&gt;open-source repository on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to implement Schema Markup for your portfolio
&lt;/h3&gt;

&lt;p&gt;Adding structured data can highlight your name, job title, websites (personal portfolio, LinkedIn, Github etc.), and projects. Here’s an example of how you can use Schema.org’s &lt;a href="https://schema.org/Person" rel="noopener noreferrer"&gt;Person&lt;/a&gt; schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    &amp;lt;script type="application/ld+json"&amp;gt;
      {
        "@context": "https://schema.org",
        "@type": "Person",
        "image": "./assets/image",
        "jobTitle": "Front End Engineer",
        "name": "Your Name",
        "url": "https://yourportfolio.com",
        "sameAs": [
          "https://github.com/yourusername",
          "https://linkedin.com/in/yourusername"
        ]
      }
    &amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test your structured data using &lt;a href="https://validator.schema.org/" rel="noopener noreferrer"&gt;Google’s Rich Results Validator&lt;/a&gt; to ensure it’s properly set up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Web Vitals: the metrics that matter in 2025
&lt;/h2&gt;

&lt;p&gt;Google now places a greater emphasis on user experience metrics, including &lt;a href="https://developers.google.com/search/docs/appearance/core-web-vitals" rel="noopener noreferrer"&gt;Core Web Vitals&lt;/a&gt;. Core Web Vitals are a set of key performance metrics that measure how users experience the speed, responsiveness, and stability of a webpage. Unlike &lt;a href="https://developer.chrome.com/docs/lighthouse/overview" rel="noopener noreferrer"&gt;Lighthouse&lt;/a&gt;, which provides lab data based on simulated environments, Core Web Vitals are field data, gathered from real users interacting with your site. These include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;LCP (Largest Contentful Paint)&lt;/strong&gt;: Measures how quickly the largest visible content (like an image or heading) loads.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;CLS (Cumulative Layout Shift)&lt;/strong&gt;: Evaluates how much elements shift around as the page loads, affecting visual stability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;INP (Interaction to Next Paint)&lt;/strong&gt;: The newest metric that focuses on how fast the page responds to user interactions like clicks and keypresses.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Core Web Vitals affect your portfolio
&lt;/h3&gt;

&lt;p&gt;A well-optimized developer portfolio should load quickly, feel responsive, and remain visually stable to create a good impression on potential employers. Poor Core Web Vitals scores can lead to a lower ranking in Google search results, making your portfolio harder to find.&lt;br&gt;
To improve your Core Web Vitals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optimize images and assets to reduce LCP&lt;/li&gt;
&lt;li&gt;Minimize layout shifts by specifying dimensions for media and fonts, therefore improving the CLS parameter&lt;/li&gt;
&lt;li&gt;Reduce JavaScript execution time and defer non-essential scripts to improve responsiveness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can use PageSpeed Insights and Chrome User Experience Report (CRUX) to track real-user performance data. Google also recently added the "Performance" tab in the Google Chrome developer tools, and you can check out your page's LCP, CLS and INP directly from your browser. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2484lutgzxzdlj03anc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2484lutgzxzdlj03anc1.png" alt="Image description" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One note for low traffic websites, the field data/CRUX will probably return "not enough data", it means that there is not enough traffic to generate a reliable report - in that case I recommend to use &lt;a href="https://www.webpagetest.org/webvitals" rel="noopener noreferrer"&gt;WebPageTest&lt;/a&gt; to analyse the website. &lt;/p&gt;
&lt;h2&gt;
  
  
  Preloading &amp;amp; optimizing assets for speed
&lt;/h2&gt;

&lt;p&gt;Here are a couple of recommendations on how to handle assets like fonts and images - optimizing these can be a quick win for performance.&lt;/p&gt;
&lt;h3&gt;
  
  
  Preloading Fonts to Reduce CLS (Cumulative Layout Shift)
&lt;/h3&gt;

&lt;p&gt;CLS issues often stem from fonts loading too slowly, causing page elements to shift unexpectedly. You can preload fonts like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;link rel="preload" href="/fonts/custom-font.woff2" as="font" type="font/woff2" crossorigin="anonymous"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, set &lt;code&gt;font-display: swap;&lt;/code&gt; in your CSS to prevent invisible text while fonts load.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lazy loading &amp;amp; optimized image formats
&lt;/h3&gt;

&lt;p&gt;Images often account for the largest portion of page weight, so optimizing them is essential.&lt;/p&gt;

&lt;p&gt;Modern formats like WebP and AVIF provide better compression than JPEG and PNG, reducing file size without sacrificing quality. &lt;/p&gt;

&lt;h3&gt;
  
  
  Implement lazy loading for images and iframes
&lt;/h3&gt;

&lt;p&gt;Lazy loading defers the loading of images and iframes until they are about to be viewed. This drastically improves initial page speed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img src="project-thumbnail.jpg" loading="lazy" alt="Project Preview"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Internal linking &amp;amp; site navigation: boosting discoverability
&lt;/h2&gt;

&lt;p&gt;Search engines rely on clear site structure and internal linking to understand the relationship between pages. If your portfolio has multiple sections—such as an "About" page, a "Projects" page, and a "Blog"—proper internal linking can help search engines crawl and index your content more efficiently.&lt;/p&gt;

&lt;p&gt;Best Practices for Internal Linking:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ensure &lt;strong&gt;every page&lt;/strong&gt; is accessible within a few clicks from the homepage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;strong&gt;descriptive anchor text&lt;/strong&gt; when linking to other pages (e.g., instead of “Click here,” use “View my latest React project”). Non-descriptive links can also lower your Lighthouse SEO score, so ensuring clarity in your anchor text benefits both usability and search rankings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you have more than 5 pages in your portfolio, add &lt;strong&gt;breadcrumb navigation&lt;/strong&gt; to help users and search engines understand your site hierarchy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include an &lt;strong&gt;HTML sitemap&lt;/strong&gt; or footer navigation links to reinforce discoverability.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Note: Since my portfolio is a two-page site, a sitemap may not be necessary in this case, but for multi-page portfolios, it can be highly beneficial. I will implement it if for example I decide to host my blog on my portfolio website&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion &amp;amp; key takeaways
&lt;/h2&gt;

&lt;p&gt;SEO for developer portfolios goes beyond just adding keywords and meta tags. To stand out in 2024, focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Structured data to enhance search engine visibility.&lt;/li&gt;
&lt;li&gt;Core Web Vitals to ensure a smooth user experience.&lt;/li&gt;
&lt;li&gt;Optimized assets and lazy loading to boost page speed.&lt;/li&gt;
&lt;li&gt;Internal linking and clear navigation to improve search engine crawling.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thank you for reading, I hope this list can be helpful.&lt;br&gt;
Here is the link to my &lt;a href="https://www.rossellaferrandino.info/" rel="noopener noreferrer"&gt;portfolio website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to ask questions and add any other recommendation you think might be useful ⚡️&lt;br&gt;
_&lt;br&gt;
[Cover image Photo by &lt;a href="https://unsplash.com/@nickmorrison?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Nick Morrison&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/macbook-pro-near-white-open-book-FHnnjk1Yj7Y?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;]_&lt;/p&gt;

</description>
      <category>seo</category>
      <category>portfolio</category>
      <category>showdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Automating Dropoff Point Retrieval in Shopify with Mechanic</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Tue, 04 Feb 2025 11:16:00 +0000</pubDate>
      <link>https://dev.to/rossellafer/automating-dropoff-point-retrieval-in-shopify-with-mechanic-5clf</link>
      <guid>https://dev.to/rossellafer/automating-dropoff-point-retrieval-in-shopify-with-mechanic-5clf</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://namastudio.it/en/blogs/blog/automazione-della-gestione-dei-punti-di-ritiro-in-shopify-con-mechanic" rel="noopener noreferrer"&gt;Nama Studio’s blog&lt;/a&gt;, sharing here for the dev community!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you're looking to streamline your workflows in Shopify, the &lt;a href="https://apps.shopify.com/mechanic" rel="noopener noreferrer"&gt;Mechanic app&lt;/a&gt; is an essential tool.&lt;/p&gt;

&lt;p&gt;It allows developers to automate tasks, saving time and simplifying operations. Mechanic provides a complete &lt;a href="https://tasks.mechanic.dev/" rel="noopener noreferrer"&gt;library of pre-built tasks&lt;/a&gt;, but we often use it to implement custom logic. When integrating external APIs, it's crucial to properly structure the tasks to manage asynchronous requests, ensure API scope detection, and follow best practices for better reliability and maintainability.&lt;/p&gt;

&lt;p&gt;In this article, I’ll show you how we built a Mechanic task that retrieves the Poste Italiane pickup point IDs from &lt;a href="https://www.shippypro.com/en/" rel="noopener noreferrer"&gt;ShippyPro&lt;/a&gt;, an advanced shipping and logistics platform—and saves them as metafields in Shopify orders.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this task does
&lt;/h2&gt;

&lt;p&gt;When customers select the &lt;strong&gt;local pickup&lt;/strong&gt; option in Shopify, the pickup point ID is not automatically saved in the order details. This was an issue for one of our clients, who needed to integrate ShippyPro to manage deliveries more efficiently.&lt;/p&gt;

&lt;p&gt;ShippyPro is a premium platform that integrates with various carriers, providing tools to automate shipments, tracking, and pickup point management. By using one of their premium APIs, we can retrieve the correct pickup point ID for an order and save it in Shopify’s metafields.&lt;/p&gt;

&lt;p&gt;Although ShippyPro and Shopify offer a native integration, due to our client’s ERP structure, orders are transmitted from Shopify to ShippyPro via API, rather than through the standard integration. This custom solution ensures that orders follow the business logic set by the ERP, while still benefiting from the advanced features of ShippyPro.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does this task work
&lt;/h2&gt;

&lt;p&gt;Here’s a general overview of how our Mechanic task works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Order Monitoring&lt;/strong&gt;: The task monitors new Shopify orders with a specific shipping method for local pickup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;API Call to ShippyPro&lt;/strong&gt;: It makes a request to ShippyPro to retrieve the available pickup points.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Saving the Pickup Point ID&lt;/strong&gt;: If a pickup point matches the customer’s selection, the ID is saved in the order’s metafields.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons learned
&lt;/h2&gt;

&lt;p&gt;During the creation of this task, we learned a lot about working with external APIs through Mechanic, particularly regarding managing asynchronous responses and correctly detecting API scopes. Let’s go over some of the key lessons we learned.&lt;/p&gt;

&lt;h3&gt;
  
  
  Managing API Scopes in Mechanic: The Role of Event Previews
&lt;/h3&gt;

&lt;p&gt;One of the main challenges in creating tasks in Mechanic is ensuring that the task has the correct API scopes to perform specific actions. Shopify requires apps to declare these scopes during installation, and Mechanic detects them by analyzing the task's code before execution.&lt;/p&gt;

&lt;p&gt;However, there’s a challenge when a GraphQL mutation (such as metafieldsSet) is executed only under specific conditions. If these conditions are not met during the preview, Mechanic might not recognize that the task needs write access to the metafields. This can lead to the task failing during execution because the necessary permissions weren’t granted during installation.&lt;/p&gt;

&lt;p&gt;To resolve this issue, we leveraged the concept of event previews. During the preview mode, we provided dummy data to ensure the metafieldsSet mutation was executed even during testing, allowing Mechanic to recognize the need for write permissions (write_orders) before actual execution.&lt;/p&gt;

&lt;p&gt;Here’s the code we used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% if event.preview %}
  {% action "shopify" %}
    mutation {
      metafieldsSet(
        metafields: [
          {
            ownerId: "gid://shopify/Order/6483826147655",
            namespace: "custom",
            key: "dropoff_point_id",
            type: "single_line_text_field",
            value: "1234"
          }
        ]
      ) {
        metafields {
          id
        }
        userErrors {
          message
        }
      }
    }
  {% endaction %}
{% endif %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How to work with external APIs in Mechanic
&lt;/h3&gt;

&lt;p&gt;Since operations in Mechanic are executed asynchronously, the results of API calls are not immediately available within the Liquid task that initiated them. To manage this, Mechanic provides a structured approach using the event subscription mechanic/actions/perform, allowing the processing to continue based on the results of the previous task.&lt;/p&gt;

&lt;p&gt;To ensure continuity between the steps, we use the meta parameter to pass additional information from the first event to the second, such as the order_id and shipping address, enabling the second event to correctly map the API response to the original order.&lt;/p&gt;

&lt;p&gt;The correct approach is to split the task into two steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First event (shopify/orders/create):&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Extract relevant data from the order with GraphQL&lt;/li&gt;
&lt;li&gt;Make the HTTP request to the external API&lt;/li&gt;
&lt;li&gt;Pass extra data using the meta object&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Second event (mechanic/actions/perform):&lt;/li&gt;
&lt;li&gt;Capture the external API response&lt;/li&gt;
&lt;li&gt;Process the response&lt;/li&gt;
&lt;li&gt;Save data to Shopify (e.g., update order metafields)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% if event.topic == "shopify/orders/create" or event.topic == "mechanic/user/order" %}
  {% capture query %}
    {% comment %}
      Build your query here
    {% endcomment %}
  {% endcapture %}

  {% assign result = query | shopify %}

  {% assign order = result.data.order %}
  {% assign shipping_address = order.shippingAddress %}

  {% if shipping_address %}
    {% assign shipping_method = order.shippingLines.edges[0].node.title %}
    {% if shipping_method == shipping_point_method %}
      {% capture parameters %}
        {
          "Method": "GetDropOffPoints",
          "Params": {
            "city": {{ shipping_address.city | json }},
            "zip": {{ shipping_address.zip | json }},
            "country": "IT",
            "couriers": ["CourierName"]
          }
        }
      {% endcapture %}

      {% action "http" %}
        {
          "method": "GET",
          "url": {{ endpoint | json }},
          "headers": {
            "Authorization": {{ ENCODED_API_TOKEN | json }},
            "Content-Type": "application/json"
          },
          "body": {{ parameters | json }},
          "meta": {
            "order_id": {{ order.id | json }},
            "order_shipping_address": {{ shipping_address.address1 | json }}
          }
        }
      {% endaction %}

    {% endif %}
  {% endif %}

  {% elsif event.topic == "mechanic/actions/perform" %}

    {% if action.type == "http" %}
      {% assign response = action.run.result.body %}
      {% assign order_id = action.options.meta.order_id %}
      {% assign order_address = action.options.meta.order_shipping_address %}
        {% if matching_point_id %}
        {% action "shopify" %}
          mutation {
            metafieldsSet(
              metafields: [
                {
                  ownerId: {{ order_id | json }},
                  namespace: "custom",
                  key: "dropoff_point_id",
                  type: "single_line_text_field",
                  value: {{ matching_point_id | json }}
                }
              ]
            ) {
               metafields {
                id
               }
               userErrors {
                 message 
               }
            }
          }

        {% endaction %}
    {% endif %}
{% endif %} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Properly structuring Mechanic tasks that interact with external APIs allows you to create powerful and reliable automations. With this solution, orders with local pickup are linked to the correct pickup point through the ShippyPro API, improving logistics efficiency and ensuring a seamless workflow.&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about working with Mechanic and external APIs, check out the &lt;a href="https://learn.mechanic.dev/techniques/responding-to-action-results" rel="noopener noreferrer"&gt;official app documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>mechanic</category>
      <category>ecommerce</category>
      <category>shippypro</category>
    </item>
    <item>
      <title>Automating your Shopify tasks with Mechanic</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Fri, 12 Mar 2021 02:39:13 +0000</pubDate>
      <link>https://dev.to/rossellafer/automating-your-shopify-tasks-with-mechanic-1hjf</link>
      <guid>https://dev.to/rossellafer/automating-your-shopify-tasks-with-mechanic-1hjf</guid>
      <description>&lt;p&gt;Running an e-commerce store on Shopify is not only selling products through various sales channels and interacting with customers. &lt;/p&gt;

&lt;p&gt;A big part of the process involves manual and repetitive tasks, like creating products, managing inventory, or fulfilling orders. &lt;/p&gt;

&lt;p&gt;Enters &lt;a href="https://apps.shopify.com/mechanic"&gt;&lt;strong&gt;Mechanic&lt;/strong&gt;&lt;/a&gt;, a Shopify App that allows merchants to automate tasks. It was written by Isaac Bowen, a person I admire a lot, and it has a very active community of developers. I have started working with Mechanic last year, but I was mostly modifying tasks already created by other developers in my team. &lt;/p&gt;

&lt;p&gt;In the past few weeks, I have been diving into the Mechanic documentation to understand how to build tasks in their entirety and on my own. There are a lot of new concepts I am encountering, mainly related to building GraphQL queries to get information about Shopify objects, as well as mutations to modify those Shopify objects.&lt;/p&gt;

&lt;p&gt;In this article you will find some general information to get started with Mechanic. The app &lt;a href="https://docs.usemechanic.com/article/421-welcome"&gt;documentation&lt;/a&gt; is really good, but I was very lost at the beginning so my notes might come in handy to other Shopify theme developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tasks and events
&lt;/h3&gt;

&lt;p&gt;As a developer, I use Mechanic to write tasks, pieces of code that respond to events. There are many types of events available in Mechanic and they might be coming from Shopify, from incoming email, from webhooks, etc. You specify the event your task responds to in the "subscriptions" field of the Mechanic task.  When the event happens, it triggers the Mechanic task, which in turn will execute the actions defined in the code.&lt;/p&gt;

&lt;p&gt;Here are some basic events available for Mechanic tasks, I'll explain each one in a couple of sentences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shopify/orders/create
mechanic/user/trigger
mechanic/scheduler/tuesday+9.hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first example &lt;code&gt;shopify/orders/create&lt;/code&gt; triggers the Mechanic task each time a new order is created. It responds to a Shopify webhook and the event will have information about that specific order, which you can then use in your task. &lt;/p&gt;

&lt;p&gt;If you want to allow the user to trigger the task by clicking on a button, you should use the &lt;code&gt;mechanic/user/trigger&lt;/code&gt; subscription. For example, I have used this event subscription, in addition to a scheduler event &lt;code&gt;mechanic/scheduler/daily&lt;/code&gt; to run a bulk scan of all the products in my store every day at midnight and check that all their variants have a price. This way my client can rely on the scheduled task, but can manually run it whenever they need.&lt;br&gt;
If you want to schedule a task for a specific time of the day, or a specific day of the week, you can play around with the &lt;code&gt;mechanic/scheduler&lt;/code&gt; event - the last example &lt;code&gt;mechanic/scheduler/tuesday+9.hours&lt;/code&gt; runs every Tuesday at 9am.&lt;/p&gt;

&lt;p&gt;You can find a comprehensive list of the events available in Mechanic &lt;a href="https://docs.usemechanic.com/article/416-all-event-topics"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Querying Shopify
&lt;/h3&gt;

&lt;p&gt;Many of the tasks I have worked on required gathering data about a specific Shopify object and then, if the object met the specified criteria, perform an action on said object. &lt;br&gt;
Generally speaking, Mechanic offers three ways of fetching data from Shopify: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Liquid objects&lt;/li&gt;
&lt;li&gt;GraphQL&lt;/li&gt;
&lt;li&gt;GraphQL bulk operations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Liquid objects return data from Shopify's REST admin API, while GraphQL and GraphQL bulk operations return data from the Shopify GraphQL's API. The key difference between the two APIs regards the way data is fetched: GraphQL queries the endpoint knowing already what data to expect, while REST retrieves all data available for that specific object.&lt;/p&gt;

&lt;p&gt;Which API is more appropriate to the task you are looking to build? In short, you should use Liquid objects when your Mechanic event is already returning an object with the data you need (for example in the case of &lt;code&gt;shopify/orders/create&lt;/code&gt; already returns the order) or if you are querying a small amount of data (if you are querying &lt;code&gt;shop.customers&lt;/code&gt; and you only have a few hundreds customers in your store).&lt;br&gt;
On the other hand, you should use the GraphQL if you have a large amount of data to scan (GraphQL bulk operations if it's very large) and if you already know what information you want to retrieve for that specific object. &lt;/p&gt;

&lt;p&gt;Let me walk you through you a couple of examples. &lt;/p&gt;
&lt;h4&gt;
  
  
  Example: REST API
&lt;/h4&gt;

&lt;p&gt;My task needs to tag a customer after he orders. In this case, my best option is to use Shopify's REST API and subscribe to the &lt;code&gt;shopify/orders/create&lt;/code&gt; event topic. &lt;/p&gt;

&lt;p&gt;The task will run every time a new order is created in Shopify and it look for the customer id within the order. Then, I using Resourceful REST, the task will perform a "shopify" action and it will add the tag "ordered" to the customer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% action "shopify" %}
  [
    "put",
    "/admin/customers/{{ order.customer.id }}.json",
    {
      "customer": {
        "tags": {{ order.customer.tags | add_tag: "ordered" | json }}
      }
    }
  ]
{% endaction %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example: GraphQL bulk operations
&lt;/h4&gt;

&lt;p&gt;My task needs to scan all products of the store and apply a tag if any of the product variants have a specific metafield.&lt;/p&gt;

&lt;p&gt;In order to achieve this, I am going to use a &lt;strong&gt;&lt;em&gt;bulk operation&lt;/em&gt;&lt;/strong&gt;, which sends Shopify a query that might return a large amount of data. As mentioned in the Mechanic documentation, "&lt;em&gt;when the query is complete, the Mechanic task is notified (with a "mechanic/shopify/bulk_operation" event), and the task then processes the query's results.&lt;/em&gt;"&lt;/p&gt;

&lt;p&gt;My task subscribes to the &lt;code&gt;mechanic/shopify/bulk_operation&lt;/code&gt; as an additional event topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mechanic/user/trigger
mechanic/shopify/bulk_operation
mechanic/scheduler/daily+8.hours
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Within my task, I have setup the script to watch for this event topic, using the bulkOperation variable to access the bulk operation's results.&lt;/p&gt;

&lt;p&gt;I will go into more details of GraphQL and bulk operations in my next article, but here are some helpful links if you want to take a look at the documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://shopify.dev/docs/admin-api/rest/reference"&gt;Shopify REST admin API reference&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://shopify.dev/docs/admin-api/graphql/reference"&gt;GraphQL admin API reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.usemechanic.com/article/358-querying-shopify#graphql-with-bulk-operations"&gt;Querying Shopify - Mechanic documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>shopify</category>
      <category>mechanic</category>
      <category>ecommerce</category>
    </item>
    <item>
      <title>How to split a string in Handlebars template</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Wed, 25 Nov 2020 11:51:40 +0000</pubDate>
      <link>https://dev.to/rossellafer/how-to-split-a-string-in-handlebars-template-33bh</link>
      <guid>https://dev.to/rossellafer/how-to-split-a-string-in-handlebars-template-33bh</guid>
      <description>&lt;p&gt;Sometimes Shopify themes will use Handlebars for components like the Shopify predictive search or the ajax cart. Handlebars compiles templates into JavaScript functions, and makes the template execution faster.&lt;/p&gt;

&lt;p&gt;So for example you could see in a theme a snippet called &lt;code&gt;predictive-template.liquid&lt;/code&gt;, which loops through the products returned by the search and outputs html including their title, price, an image etc.&lt;/p&gt;

&lt;p&gt;This is what a Handlebars template will look like - I got this from a paid Shopify theme I was adding custom functionality to today:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div&amp;gt;
    {% raw %}
      {{#if products}}
        &amp;lt;div data-type-products&amp;gt;
          &amp;lt;div class="grid grid--uniform"&amp;gt;
            {{#products}} 
          &amp;lt;div class="grid-product__meta"&amp;gt;
            &amp;lt;div"&amp;gt;{{title}}&amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
          {{#if image }}
           &amp;lt;img class="image-fit lazyload"
             data-src="{{image}}"
             data-widths="[180, 360, 540, 720]"
             data-sizes="auto"&amp;gt;
          {{/if}}
         &amp;lt;/div&amp;gt;
     &amp;lt;/div&amp;gt;
{% endraw %}
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Variables like title or image are returned from the get request to the endpoint &lt;code&gt;search/suggest.json&lt;/code&gt;, which is made in a JavaScript file like &lt;code&gt;theme.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What I wanted to do today was manipulate the product title string to remove the first 10 letters. In order to do that in Handlebars, I created a helper, which I then added to the JavaScript file that was handling the template compilation. The documentation on how to use registerHelper in Handlebars is &lt;a href="https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerhelper-name-helper"&gt;here&lt;/a&gt;&lt;br&gt;
This is my code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Handlebars.registerHelper('sliceTitle', function(passedString) {
  var theString = passedString.substring(10,100);
    return new Handlebars.SafeString(theString)
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Handlebars.SafeString(string) is a built in helper that prevents string from being escaped when the template is rendered. &lt;br&gt;
Finally, I modified the Handlebars template to use the helper just created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div class="grid-product__meta"&amp;gt;
  &amp;lt;div"&amp;gt;{{sliceTitle title}}&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, this is how I created my custom Handlebars helper to manipulate the results returned from the predictive search and outputted using a Handlebars template.&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>handlebars</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Planning your first technical workshop</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Mon, 23 Nov 2020 10:47:13 +0000</pubDate>
      <link>https://dev.to/rossellafer/planning-your-first-technical-workshop-2iig</link>
      <guid>https://dev.to/rossellafer/planning-your-first-technical-workshop-2iig</guid>
      <description>&lt;p&gt;While I was learning how to code back in London, I used to attend the workshops organised by &lt;a href="https://codebar.io/" rel="noopener noreferrer"&gt;Codebar&lt;/a&gt;, where junior developers were paired with a mentor and going through their tutorial/projects with the help of an expert developer. &lt;br&gt;
After I moved to Tokyo, I started attending the events organised by associations like &lt;a href="https://www.womenwhocode.com/tokyo" rel="noopener noreferrer"&gt;Women Who Code&lt;/a&gt;, or coding bootcamps like &lt;a href="https://www.lewagon.com/tokyo" rel="noopener noreferrer"&gt;Le Wagon&lt;/a&gt; and &lt;a href="https://www.codechrysalis.io/" rel="noopener noreferrer"&gt;Code Chrysalis&lt;/a&gt;. There are just so many good events happening in the tech industry that I didn't want to miss anything. &lt;/p&gt;

&lt;p&gt;I have received so much by participating to technical workshops and attending networking events. So this year I decided to start giving back to the tech community that has given so me so much. I signed up as a volunteer with &lt;strong&gt;Women Who Code Tokyo&lt;/strong&gt;, where I have helped organising a couple of their events and even contributed to their open source project SpeakHer. &lt;/p&gt;

&lt;p&gt;So when a colleague recommended me for a technical workshop organised by Le Wagon, I decided to take a leap and contact the event organiser to host the workshop. &lt;br&gt;
Sasha, the community manager for Le Wagon, is also an active member of Women Who Code, so it was the perfect opportunity for me to have my first tech talk in a supportive and familiar environment. &lt;/p&gt;

&lt;p&gt;Together we discussed the broad topic of the event, focused on Customising a Shopify store using the templating language Liquid. It's a great topic for me because it's what I do for a living. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmqr4mujkcx9bu5zl25t7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmqr4mujkcx9bu5zl25t7.png" alt="event_banner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I want to use this post to put together some of the things I learned while preparing this technical workshop. They might be helpful if you are going through the same thing, and I check them out again if I decide to host another workshop.&lt;/p&gt;

&lt;h4&gt;
  
  
  Plan for your target audience
&lt;/h4&gt;

&lt;p&gt;The topic of the workshop is usually set by the event organisers, but as a speaker you can approach that topic from a specific angle. Have a type of target audience in mind, as well as what you would like them to take away from your workshop. I really appreciate people investing their time in learning something new, listening to a tech talk and actively participating in the discussion, so I wanted them to get something valuable from the hour they decided to spend with me.&lt;/p&gt;

&lt;p&gt;I planned the practical part of my workshop around 3 learning outcomes I wanted the listeners to achieve by the end of the talk. And I prepared a specific slide that I discussed just after the agenda, so that it was clear to everybody what the practical outcomes should have been.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1e0mto72f8021w6ynfkg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1e0mto72f8021w6ynfkg.png" alt="Learning outcomes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Have a clear structure
&lt;/h4&gt;

&lt;p&gt;One hour is a lot of time and you need to make sure you keep the audience's attention level quite consistent throughout the whole presentation. I broke down my workshop in two main parts, one focused on introducing the topic and give some theoretical background, and the other one focused on building something together, so that the concepts introduced in part 1 could be applied straight away. This is the agenda I put together, sections from 1 to 3 were focused on theory, sections 4 and 5 on live coding, and then the last section was where I wrapped things up and recommended some resources to continue learning about the topic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqe2nrt8mlw257fzjy2a5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqe2nrt8mlw257fzjy2a5.png" alt="Workshop agenda"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Slides
&lt;/h4&gt;

&lt;p&gt;This is a topic I learned a lot about, thanks to the "Intro to public speaking" workshop organised by Women Who Code Tokyo. Here are some small takeaways I applied to my presentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Plain colours that don't distract the audience too much&lt;/li&gt;
&lt;li&gt;Use the same pattern/slide type to break down each section of the workshop, like you had listed in the agenda. So in my case, I had a slide with the same background throughout the whole presentation, with just the title of the new workshop section&lt;/li&gt;
&lt;li&gt;Don't use too many words on the slides, so people will listen to what you have to say instead of reading the content&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Write a script for the whole talk and rehearse it
&lt;/h4&gt;

&lt;p&gt;In the weeks leading up to the workshop, I worked on my presentation, created my Shopify store, uploaded products for the demo, as well as coded the necessary parts I was going to go through during the practical theme development part. &lt;br&gt;
In my head everything was ready, but when I started rehearsing, I realised I wasn't really prepared to present. I knew what I wanted to say but I didn't know the best way of expressing it. What really helped was writing down a script with everything I wanted to say and then read it so many times I could actually deliver it convincingly. &lt;/p&gt;

&lt;h4&gt;
  
  
  Have your code snippets ready
&lt;/h4&gt;

&lt;p&gt;This is something I had never noticed with all the workshops I attended, but instructors usually have their code snippets ready on another window/screen. The audience doesn't really want to see you type large chunks of code, but you can paste the code you already have ready, and then go through each line and explain what that code does and why it works.&lt;br&gt;
During my workshop, I had two screens: one with the presentation, as well as my code editor and browser windows to edit the themes, and another one just with the code snippets, each opened already in a different tab. &lt;/p&gt;

&lt;h4&gt;
  
  
  Relax, you are the expert here
&lt;/h4&gt;

&lt;p&gt;One final key takeaway is not to stress out too much before the workshop. You are prepared and you are donating your time to teach other people something you know well. You know more about that specific topic than the other people in the room. I have learned from someone wise that, if there are difficult questions in the Q&amp;amp;A session, it's ok to say "let's take this offline". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gifer.com%2FawZ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.gifer.com%2FawZ.gif" alt="You got this"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thank you so much for reading, feel free to share some more recommendations for first time public speakers in the comments. &lt;/p&gt;

</description>
      <category>speaking</category>
      <category>shopify</category>
      <category>womenintech</category>
      <category>career</category>
    </item>
    <item>
      <title>Making the world a better place with open source</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Sat, 10 Oct 2020 05:20:33 +0000</pubDate>
      <link>https://dev.to/rossellafer/making-the-world-a-better-place-with-open-source-2j0a</link>
      <guid>https://dev.to/rossellafer/making-the-world-a-better-place-with-open-source-2j0a</guid>
      <description>&lt;p&gt;About a month ago, I submitted my very first pull request to an open source project on Github. It felt like using my coding "superpowers" for the greater good. Let me tell you a bit more about my journey and how I found a good first project to contribute to. &lt;/p&gt;

&lt;h4&gt;
  
  
  Why open source
&lt;/h4&gt;

&lt;p&gt;I have been trying to contribute to open source for about two years now. That's right, two years. I had always read that this is one of the best ways to step up your coding skills. It allows you to learn how to work collaboratively, to read code written by experienced developers and to meet people interested in similar things. I had the drive and motivation, all that was missing was a project to contribute to. &lt;/p&gt;

&lt;p&gt;I searched for issues using the recommended issue aggregators such as &lt;a href="https://up-for-grabs.net/#/" rel="noopener noreferrer"&gt;Up For Grabs&lt;/a&gt; or &lt;a href="https://www.codetriage.com/" rel="noopener noreferrer"&gt;Code Triage&lt;/a&gt;, I had even bookmarked a Github search with a filter for all issues tagged as "good first issue", which I checked regularly. But every time I went through a specific repository, I was overwhelmed with self doubt and intimidated by the code base, so I got discouraged and eventually gave up. &lt;/p&gt;

&lt;p&gt;This year, I got more involved in the Women Who Code Tokyo community. I had attended their events for almost two years and I decided to step up and help organize some of the upcoming workshops and events. &lt;br&gt;
Then I heard about SpeakHer, made by three amazing women in this network and for a really good cause, so I decided to give open source another go. &lt;/p&gt;

&lt;h4&gt;
  
  
  SpeakHer
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjg0eyi9476wmkj3l9zez.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjg0eyi9476wmkj3l9zez.png" alt="SpeakHer hero image"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://speakher.jp/" rel="noopener noreferrer"&gt;SpeakHer&lt;/a&gt; is a bilingual database of public female speakers in Japan and it has the purpose of reducing the imbalance of presenters at conferences and other events. It allows event organizers to search for female speakers and fellow speakers to connect and support each other. &lt;br&gt;
The project is a serverless Vue.js site hosted on Netlify and using Airtable as database. &lt;/p&gt;

&lt;p&gt;As I was already part of their network, I joined a Zoom call with the project maintainers, explained my background and got assigned to a couple of good first issues. The purpose of this type of Github issues is to allow new contributors to get familiar with the codebase and to make a minor improvement to the site. I really admire the project maintainers for their passion and patience in mentoring new contributors to the project 👏&lt;br&gt;
This is SpeakHer &lt;a href="https://github.com/WWCodeTokyo/speak-her-db" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt; if you would like to check it out. &lt;/p&gt;

&lt;h4&gt;
  
  
  What I am learning
&lt;/h4&gt;

&lt;p&gt;I have now made two contributions to this project, mostly focused on form validations. The skills I am improving are definitely &lt;strong&gt;communication skills&lt;/strong&gt;, as I need to explain why I am making a certain type of changes to the code and &lt;strong&gt;technical skills&lt;/strong&gt; such as navigating a new codebase, using following consistent naming conventions and reading documentation to implement what is required. &lt;/p&gt;

&lt;p&gt;In conclusion, I would recommend contributing to open source, not only to leave your mark in projects that could have a positive impact on people, but to also learn and improve technically. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>speakher</category>
      <category>womenintech</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>SEO tips for your developer portfolio</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Mon, 31 Aug 2020 13:47:15 +0000</pubDate>
      <link>https://dev.to/rossellafer/seo-tips-for-your-developer-portfolio-26fm</link>
      <guid>https://dev.to/rossellafer/seo-tips-for-your-developer-portfolio-26fm</guid>
      <description>&lt;p&gt;As a front-end developer, I am often working on client websites to optimise their SEO. This week, I applied some of these strategies to my developer portfolio, which now has a 100 SEO score on Lighthouse 👩‍💻.&lt;br&gt;&lt;br&gt;
I will share some advice with you here. By all means, this is not an exhaustive list but it's a good place to start. If you want to check out my portfolio, I added a link to this at the bottom of the article.&lt;/p&gt;
&lt;h3&gt;
  
  
  Title, language and viewport
&lt;/h3&gt;

&lt;p&gt;Probably quite obvious, but your portfolio should have a title. You can specify this in the html head as &lt;code&gt;&amp;lt;title&amp;gt;My portfolio&amp;lt;/title&amp;gt;&lt;/code&gt;.&lt;br&gt;
What is not so obvious is that defining the language and the viewport on your site will impact your Lighthouse score. The language is important for those users that utilise screen readers, while the viewport meta tag will optimise your app for mobile screens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;meta
      name="viewport"
      content="width=device-width, initial-scale=1, 
      shrink-to-fit=no"
    /&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Meta tags
&lt;/h3&gt;

&lt;p&gt;Meta tags are snippets of code that give search engines information about your website. The basic ones are title, which I already mentioned, and description. This is the information that is displayed in the Google search results, so it should be concise and to the point. You can also add keywords to your page, but I haven't implemented this yet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;meta name="description" content="JavaScript wizard, chaotic good"&amp;gt;
&amp;lt;meta name="keyword" content="portfolio, javascript, developer"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Meta tags for social media
&lt;/h3&gt;

&lt;p&gt;This is not 100% necessary, but it is a nice to have if you want to share your portfolio on Slack, Twitter, etc.&lt;br&gt;
These meta tags turn your web pages into graph objects through the &lt;a href="https://ogp.me/" rel="noopener noreferrer"&gt;Open Graph Protocol&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;meta property="og:title" content="Myrtis Beaverdam | Front End Web Developer"/&amp;gt;
&amp;lt;meta property="og:description" content="JavaScript wizard, chaotic good" /&amp;gt;
&amp;lt;meta property="og:image" content="https://example.com/image.jpg"/&amp;gt;
&amp;lt;meta property="og:url" content="https://example.com" /&amp;gt;
&amp;lt;meta property="og:type" content="website" /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Twitter has its own set of meta tags. You can either use the summary card (title, thumbnail image and description) or the summary card with large image, which is the one I prefer. This is an example markup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;meta name="twitter:card" content="summary_large_image" /&amp;gt;
&amp;lt;meta name="twitter:title" content="Myrtis Beaverdam | Front End Developer" /&amp;gt;
&amp;lt;meta name="twitter:description" content="JavaScript wizard, chaotic good"/&amp;gt;
&amp;lt;meta name="twitter:image" content="https://example.com/image.jpg"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to check what your Twitter card will look like, you can use the Twitter card validator here: &lt;a href="https://cards-dev.twitter.com/validator" rel="noopener noreferrer"&gt;https://cards-dev.twitter.com/validator&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Accessibility
&lt;/h3&gt;

&lt;p&gt;Two important points related to accessibility impact your SEO score, however Lighthouse reports have many more insights on accessibility, which I highly recommend checking.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Images need to have descriptive &lt;code&gt;alt&lt;/code&gt; attributes. If the &lt;code&gt;alt&lt;/code&gt; attribute is just an empty string, this will be removed from the accessibility tree. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another point related to accessibility that I discovered with this portfolio iteration is the that each anchor tag should have some descriptive text. Using anchor tags with icons (and not text) for my social media profiles was negatively impacting my score, and I discovered that attribute &lt;code&gt;aria-label&lt;/code&gt; resolves this particular issue.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Favicon
&lt;/h3&gt;

&lt;p&gt;This is a bonus tip and it is not really related to SEO (but it's a nice to-have). You can include a favicon in your project. This is what will be displayed in the browser tab, just before your website title. This is how you add it to your code:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;link rel="shortcut icon" href="./assets/favicon.ico" type="image/x-icon" /&amp;gt;&lt;/code&gt;&lt;/p&gt;




&lt;p&gt;Thank you for reading, I hope this list can be helpful. &lt;br&gt;
Here is the link to my &lt;a href="https://rossellafer.github.io/fcc-portfolio/" rel="noopener noreferrer"&gt;portfolio website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to ask questions and add any other recommendation you think might be useful ⚡️&lt;/p&gt;

</description>
      <category>html</category>
      <category>portfolio</category>
      <category>showdev</category>
      <category>seo</category>
    </item>
    <item>
      <title>Learning Ruby: check equality</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Sun, 16 Aug 2020 10:01:15 +0000</pubDate>
      <link>https://dev.to/rossellafer/learning-ruby-check-equality-51ng</link>
      <guid>https://dev.to/rossellafer/learning-ruby-check-equality-51ng</guid>
      <description>&lt;p&gt;There are different ways to determine whether two values are the same in Ruby. &lt;/p&gt;

&lt;h4&gt;
  
  
  Equality operators: == and !=
&lt;/h4&gt;

&lt;p&gt;The equals operator == will return &lt;code&gt;true&lt;/code&gt; if the values compared are equal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;string_one = "Cookies"
string_two = "Cookies"

string_one == string_two   #Output: =&amp;gt; true
string_one != string_two   #Output: =&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we compare numbers of different types (float and integer), the equals operator will return true if both have the same numeric value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7 == 7.0   #Output: =&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  eql?
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;eql?&lt;/code&gt; method checks both the value type and the exact value it holds. So an integer and a float that have the same numeric value will not be equal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;7.eql?(7.0)   #Output: =&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  equal?
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;equal?&lt;/code&gt; method is the strictest form of comparison in Ruby. It checks whether both values are the exact same object in memory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = "Cookies"
b = "Cookies"

puts a.object_id #Output: =&amp;gt; 47343105968220
puts b.object_id #Output: =&amp;gt; 47343105968200

a.equal? b  # Output: =&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Things are a bit different for numbers, because of the way computers store integers in memory. 7 will always point at the same object id, so if we assign the number 7 to two different variables and use the &lt;code&gt;equal?&lt;/code&gt; method on those two variables, the result will be true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = 7
b = 7

puts a.object_id # Output: =&amp;gt; 15
puts b.object_id # Output: =&amp;gt; 15

puts a.equal?(b)  # Output: =&amp;gt; true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  The spaceship operator &amp;lt;=&amp;gt;
&lt;/h4&gt;

&lt;p&gt;Differently from the previous operators / methods, the spaceship operator does not return true or false, but it returns one of three numerical values. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-1&lt;/code&gt; if the value on the left is less than the value on the right&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt; if the value on the left is equal to the value on the right&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; if the value on the left is greater than the value on the right
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
7 &amp;lt;=&amp;gt; 8 # Output: =&amp;gt; -1
7 &amp;lt;=&amp;gt; 7.0 # Output: =&amp;gt; 0
7 &amp;lt;=&amp;gt; 7 # Output: =&amp;gt; 0
7 &amp;lt;=&amp;gt; 1 # Output: =&amp;gt; 1

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This operator is mostly used for sorting functions. &lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Ruby: string concatenation</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Sat, 08 Aug 2020 07:13:08 +0000</pubDate>
      <link>https://dev.to/rossellafer/learning-ruby-string-concatenation-45kd</link>
      <guid>https://dev.to/rossellafer/learning-ruby-string-concatenation-45kd</guid>
      <description>&lt;p&gt;I have been practicing my Ruby beginner skills on Codewars this week and I just came across this interesting Kata which taught me something new about concatenating strings. &lt;/p&gt;

&lt;p&gt;The description of the &lt;a href="https://www.codewars.com/kata/50654ddff44f800200000007/solutions/ruby"&gt;Kata&lt;/a&gt; is as follows: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Given 2 strings, a and b, return a string of the form short+long+short, with the shorter string on the outside and the longer string on the inside. &lt;br&gt;
The strings will not be the same length, but they may be empty ( length 0 ).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;solution("1", "22") # returns "1221"
solution("22", "1") # returns "1221"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, I tried using the &lt;code&gt;concat&lt;/code&gt; method, similarly to what I would do in JavaScript. I was surprised when the output of my function was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def solution(a, b)
  puts a.length &amp;gt; b.length ? b.concat(a).concat(b) : a.concat(b).concat(a)
end

solution("a", "bb") 
# returns "abbabb"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As a matter of fact the &lt;code&gt;concat&lt;/code&gt; method in Ruby will change the initial string, and that is why the last &lt;code&gt;.concat(a)&lt;/code&gt; was concatenating an incorrect value. The same happens when you use the method &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt;, which is equivalent to &lt;code&gt;concat&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order to resolve the Kata, I used the + operators, which does not mutate the initial string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def solution(a, b)
  puts a.length &amp;gt; b.length ? b + a + b : a + b + a
end

solution("a", "bb") 
# returns "abba"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Summary
&lt;/h4&gt;

&lt;p&gt;In Ruby, there are various ways to concatenate two or more strings: &lt;/p&gt;

&lt;h5&gt;
  
  
  + operator
&lt;/h5&gt;

&lt;p&gt;Strings can be appended to one another using the + operator, like in JavaScript and other languages. This will not modify the initial string.&lt;/p&gt;

&lt;h5&gt;
  
  
  concat method
&lt;/h5&gt;

&lt;p&gt;This method will change the string instead of creating a new one.&lt;/p&gt;

&lt;h5&gt;
  
  
  &amp;lt;&amp;lt; method
&lt;/h5&gt;

&lt;p&gt;This is an alias for concat and it also mutates the initial string.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Learning Ruby: naming conventions</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Wed, 05 Aug 2020 13:03:23 +0000</pubDate>
      <link>https://dev.to/rossellafer/learning-ruby-naming-conventions-5286</link>
      <guid>https://dev.to/rossellafer/learning-ruby-naming-conventions-5286</guid>
      <description>&lt;p&gt;Ruby has specific naming conventions that make it easier to write and read code. I would like to summarize them here in a cheatsheet format that is easier to refer to.&lt;/p&gt;

&lt;p&gt;snake_case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;files&lt;/li&gt;
&lt;li&gt;variables&lt;/li&gt;
&lt;li&gt;methods
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#files
my_first_ruby_file.rb

#variables
programming_language = "Ruby"

#methods
def make_an_example
  #do stuff
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;UPPERCASE:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;constant variables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Constant variables represent values that will not change during your Ruby program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ID = AB123456
FAVORITE_FOOD = "Pizza"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CamelCase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;classes
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person
end

class Movie
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Additional note
&lt;/h4&gt;

&lt;p&gt;When working with do/end blocks, it is preferable to use { } when the code can fit in a single line&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;characters = ["Eleven", "Mike", "Dustin", "Lucas", "Will"]
characters.each do |character|
  puts character
end

characters.each { |character| puts character }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
    <item>
      <title>👩‍💻 Learning Ruby: first impressions from a JavaScript developer</title>
      <dc:creator>Rossella Ferrandino</dc:creator>
      <pubDate>Tue, 04 Aug 2020 14:53:07 +0000</pubDate>
      <link>https://dev.to/rossellafer/learning-ruby-first-impressions-from-a-javascript-developer-1d11</link>
      <guid>https://dev.to/rossellafer/learning-ruby-first-impressions-from-a-javascript-developer-1d11</guid>
      <description>&lt;p&gt;I have just finished the last class of the &lt;a href="https://info.lewagon.com/programming-for-everybody-tokyo"&gt;"Le Wagon - Programming for Everybody"&lt;/a&gt; online learning series. This was my very first dip into the world of Ruby... and I must admit, I was surprised to discover how developer friendly and humanly readable this language is. &lt;/p&gt;

&lt;h3&gt;
  
  
  Why Ruby
&lt;/h3&gt;

&lt;p&gt;You might be wondering, why did a professional developer decide to join a beginner course about Ruby? First of all, a little bit about myself. I am a self-taught developer and I got a job as a front end developer after learning how to code on Freecodecamp, Codecademy and just building projects. &lt;/p&gt;

&lt;p&gt;I wanted to experience a structured learning course with a real instructor, where I could ask questions not only about the syntax, but also about best practices and why Ruby does things the way it does. By the end of the course, I also realised that learning a language like Ruby can make me a better JavaScript developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ruby and JavaScript: some observations
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Object Oriented Programming
&lt;/h4&gt;

&lt;p&gt;Ruby is an &lt;strong&gt;Object Oriented Language&lt;/strong&gt;, which means it manipulates programming constructs called objects. If you type &lt;code&gt;"Ruby"&lt;/code&gt;, you are creating an instance of the class String. As a class instance, your string will inherit methods like &lt;code&gt;.length&lt;/code&gt;, &lt;code&gt;.capitalize&lt;/code&gt; etc., that you can use to manipulate your string.&lt;/p&gt;

&lt;p&gt;JavaScript, on the other hand, is not a class-based Object Oriented language, but with prototype based inheritance and constructor functions, it has ways of using Object Oriented Programming (OOP). &lt;/p&gt;

&lt;h4&gt;
  
  
  Data types
&lt;/h4&gt;

&lt;p&gt;To determine what type of value something is (a number, a string, an array), in Ruby you append &lt;code&gt;.class&lt;/code&gt; at the end of the object, since you want to find out the class of the object it's called on. There are classes like Integer, Float, String, Array, Hash... even True and False are their own class!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;true.class
# TrueClass

false.class
# FalseClass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JavaScript, you use &lt;code&gt;typeof&lt;/code&gt; before your data, and this will return whether that element is a string, a number, a boolean, an object etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typeof true
# boolean

typeof false
# boolean
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Method naming conventions
&lt;/h4&gt;

&lt;p&gt;In Ruby, I saw for the first time methods ending with "?", a naming convention used to indicate that a specific method will return either true or false. For example, if you have a hash (a key value pair data structure) with tv show titles and ratings, you can use the simple method &lt;code&gt;.key?&lt;/code&gt; to check if the hash contains a certain key.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tv_shows = {
  "Friends" =&amp;gt;  10,
  "Community" =&amp;gt; 10,
  "The Witcher" =&amp;gt; 9
}

puts tv_shows.key?("Friends")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In JavaScript, functions can't end with punctuation but can be named semantically so that their name will describe well what they do. If you are curious to know how you can check if an object has a specific key in JavaScript, this is how you do it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const tv_shows = {
  "Friends": 10,
  "Community": 10,
  "The Witcher": 9
}

tv_shows.hasOwnProperty("Friends")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  There is more than one way to do something
&lt;/h4&gt;

&lt;p&gt;Ruby is built for usability. I was surprised to discover that for example the methods &lt;code&gt;.map&lt;/code&gt; and &lt;code&gt;.collect&lt;/code&gt; do exactly the same thing and that collect was just created in order to make Ruby feel more intuitive. &lt;/p&gt;

&lt;h3&gt;
  
  
  Where to go from here?
&lt;/h3&gt;

&lt;p&gt;I plan on continuing learning Ruby until I am able to contribute to my company's projects that use this language. That's how I would like to reinforce this initial knowledge and put it into practice:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Codewars kata&lt;/li&gt;
&lt;li&gt;Build a scraper - apparently this can be done only with a few lines of code in Ruby&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.theodinproject.com/courses/ruby-programming"&gt;The Odin Project learning track&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>ruby</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
