<?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: IndiSnw</title>
    <description>The latest articles on DEV Community by IndiSnw (@indisnw).</description>
    <link>https://dev.to/indisnw</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%2F1140169%2F329af531-9127-42fa-a377-bd908753d6c5.jpeg</url>
      <title>DEV Community: IndiSnw</title>
      <link>https://dev.to/indisnw</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/indisnw"/>
    <language>en</language>
    <item>
      <title>Building a Lightweight Landing Page Without React and almost no code</title>
      <dc:creator>IndiSnw</dc:creator>
      <pubDate>Wed, 04 Dec 2024 14:28:09 +0000</pubDate>
      <link>https://dev.to/indisnw/building-a-lightweight-landing-page-without-react-and-almost-no-code-17oe</link>
      <guid>https://dev.to/indisnw/building-a-lightweight-landing-page-without-react-and-almost-no-code-17oe</guid>
      <description>&lt;h2&gt;
  
  
  The Overhyped Framework Problem
&lt;/h2&gt;

&lt;p&gt;Let's be real - do you really need React for a simple landing page? Spoiler: Nope. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Lightweight Approach
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Ask claude.ai generate a landing website&lt;/li&gt;
&lt;li&gt;Sign up on netlify&lt;/li&gt;
&lt;li&gt;Add a netlify config to your git repo
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[build]
  publish = "."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it your website is published upon every github push.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;I tried this approach on &lt;a href="https://www.tax-invoice.indisnw.com/" rel="noopener noreferrer"&gt;Shopify Tax Invoices&lt;/a&gt; app website. Works incredibly well. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to handle form submission
&lt;/h2&gt;

&lt;p&gt;If you don't need to store the data and can maybe send emails for contact us form you can just add a simple "netlify" to your plain html form and netlify will save the data on their server. It's for free... Looks 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;form id="affiliateForm" class="space-y-6" netlify&amp;gt;
                    &amp;lt;div&amp;gt;
                        &amp;lt;label for="name" class="block text-sm font-medium text-gray-700"&amp;gt;Full Name&amp;lt;/label&amp;gt;
                        &amp;lt;input type="text" name="name" id="name" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring-primary"&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div&amp;gt;
                        &amp;lt;label for="email" class="block text-sm font-medium text-gray-700"&amp;gt;Email Address&amp;lt;/label&amp;gt;
                        &amp;lt;input type="email" name="email" id="email" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring-primary"&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div&amp;gt;
                        &amp;lt;label for="website" class="block text-sm font-medium text-gray-700"&amp;gt;Website/Blog (optional)&amp;lt;/label&amp;gt;
                        &amp;lt;input type="url" name="website" id="website" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring-primary"&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div&amp;gt;
                        &amp;lt;label for="promotion" class="block text-sm font-medium text-gray-700"&amp;gt;How will you promote Tax Invoice?&amp;lt;/label&amp;gt;
                        &amp;lt;textarea name="promotion" id="promotion" rows="4" required class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-primary focus:ring-primary"&amp;gt;&amp;lt;/textarea&amp;gt;
                    &amp;lt;/div&amp;gt;

                    &amp;lt;div&amp;gt;
                        &amp;lt;button type="submit" class="w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-primary hover:bg-primary-dark focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"&amp;gt;
                            Submit Application
                        &amp;lt;/button&amp;gt;
                    &amp;lt;/div&amp;gt;
                &amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Challenges
&lt;/h2&gt;

&lt;p&gt;The approach overall is robust but after about 3 pages you might run into some challenges, such as.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Difficulty updating common components such as footer using cursor.ai. Sometimes it will just say "Go and updated yourself"&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>DIY Image gallery for Shopify blog posts</title>
      <dc:creator>IndiSnw</dc:creator>
      <pubDate>Wed, 16 Aug 2023 13:53:00 +0000</pubDate>
      <link>https://dev.to/indisnw/diy-image-gallery-for-shopify-blog-posts-4pjh</link>
      <guid>https://dev.to/indisnw/diy-image-gallery-for-shopify-blog-posts-4pjh</guid>
      <description>&lt;p&gt;For the past few months, I've been busy with a Shopify website project. Recently, my client began focusing on content marketing, and over the last two weeks, they ran into an issue. They couldn't add image galleries to their blog posts using the content manager.&lt;/p&gt;

&lt;p&gt;I did some research, and to my surprise, Shopify doesn't allow adding galleries to a blog post. All it offers is a rich text editor and the option to insert single images.&lt;/p&gt;

&lt;p&gt;Some folks recommend switching to a dedicated blogging platform like WordPress. However, that approach didn't suit me since it would mean more effort. So, I came up with a clever and user-friendly workaround instead.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;p&gt;The solution involves just one JavaScript and one CSS file. After it's all set up, you won't need any coding skills to use it. I believe even someone without coding experience can handle the setup.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to set up
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Add this CSS to your website's assets. I simply made a separate file called "blog-carousel.css" in the assets folder. It only includes CSS styles for the gallery, with no need for third-party dependencies.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Slideshow container */
.slideshow__photo {
    max-width: 500px;
    position: relative;
    margin: auto;
}

.slideshow-container {
    margin-bottom: 32px;
}


/* Next &amp;amp; previous buttons */
.slideshow__prev, .slideshow__next {
    cursor: pointer !important;
    position: absolute;
    top: 50%;
    width: auto;
    margin-top: -22px;
    padding: 16px;
    color: white !important;
    font-weight: bold;
    font-size: 18px;
    transition: 0.6s ease !important;
    border-radius: 0 3px 3px 0 !important;
    user-select: none !important;
}

/* Position the "next button" to the right */
.slideshow__next {
    right: 0;
    border-radius: 3px 0 0 3px;
}

/* On hover, add a black background color with a little bit see-through */
.slideshow__prev:hover, .slideshow__next:hover {
    background-color: rgba(0,0,0,0.8);
}

.slideshow__thumbnails {
    display: flex;
    justify-content: center;
}

.slideshow__thumbnails img {
    max-width: 200px;
    max-height: 170px;
    margin-left: 3px;
    margin-right: 3px;
    cursor: pointer;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2.Add this js file that will initialize the galleries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function slideShowChangeImage(e) {
    const newUrl = e.src;
    const img = e.parentNode.parentNode.getElementsByClassName('slideimg');
    img[0].src=newUrl;
}

function slideShowPrev(e) {
    changeToNextOrPrevImage(e, -1);
}

function slideShowNext(e) {
    changeToNextOrPrevImage(e, 1);
}

function getAllGalleryImages(parent) {
    const images = parent.getElementsByClassName('gallery-thumbnail');
    let allUrls = [];
    for (let i = 0; i &amp;lt; images.length; ++i) {
        allUrls.push(images[i].src);
    }
    return allUrls;
}

function changeToNextOrPrevImage(e, change){
    // get all available images

    // try to find the next one
    let allUrls = getAllGalleryImages(e.parentNode.parentNode);

    const img = e.parentNode.getElementsByClassName('slideimg');
    const currentUrl = img[0].src;

    const pos = allUrls.findIndex(v =&amp;gt; currentUrl === v);
    let nextSlide = pos + change;
    if (nextSlide &amp;lt; 0) {
        nextSlide = allUrls.length - 1;
    } else {
        nextSlide = nextSlide % allUrls.length;
    }

    img[0].src = allUrls[nextSlide];
}

function initImageGalleries() {
    for (let i = 0; i &amp;lt;= 15; ++i) {
        createGallery(i.toString().padStart(2, '0'));
    }
}

function createGallery(id) {
    // get galleries grouped by number
    let allImages = document.querySelectorAll(`img[alt*="gallery ${id}"]`);

    let imgInCurrentGallery = [];
    let parent;

    let galleryStartNode = null;

    // delete the old images
    for(let i = 0; i &amp;lt; allImages.length; ++i) {
        const img = allImages[i];

        imgInCurrentGallery.push(allImages[i].cloneNode(true));

        parent = img.parentNode.parentNode;
        if (!galleryStartNode) {
            galleryStartNode = img.parentNode.nextSibling;
            console.log(galleryStartNode);
        }

        img.parentNode.remove();
    }

    if (allImages.length &amp;gt; 0) {
        buildGalleryHtml(parent, galleryStartNode, imgInCurrentGallery);
    }

    return allImages.length &amp;gt; 0;
}

function buildGalleryHtml(parent, insertBefore, imgs) {
    // class="slideshow-container"
    const container = document.createElement('div');
    container.className = 'slideshow-container';

    // init controls
    const controlsHtml = ` &amp;lt;div class="slideshow__photo"&amp;gt;
                &amp;lt;div class="mySlides"&amp;gt;
                    &amp;lt;img class="slideimg" src="" style="width:100%"&amp;gt;
                &amp;lt;/div&amp;gt;

                &amp;lt;a class="slideshow__prev" onclick="slideShowPrev(this)"&amp;gt;&amp;amp;#10094;&amp;lt;/a&amp;gt;
                &amp;lt;a class="slideshow__next" onclick="slideShowNext(this)"&amp;gt;&amp;amp;#10095;&amp;lt;/a&amp;gt;
                &amp;lt;br&amp;gt;
            &amp;lt;/div&amp;gt;`;
    container.innerHTML = controlsHtml;

    // init thumbnails
    const thumbNailsSection = document.createElement('div');
    thumbNailsSection.className = 'slideshow__thumbnails';
    container.append(thumbNailsSection);

    for(let i = 0; i &amp;lt; imgs.length; ++i) {
        const img = document.createElement('img');
        img.className = 'gallery-thumbnail';
        img.src = imgs[i].src;
        img.addEventListener('click', () =&amp;gt; slideShowChangeImage(img));
        thumbNailsSection.appendChild(img);
    }

    // set image to the first
    const img = container.getElementsByClassName('slideimg');
    img[0].src = imgs[0].src;

    parent.insertBefore(container, insertBefore);
}

document.addEventListener('DOMContentLoaded', () =&amp;gt; initImageGalleries());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Add those two files to your website. I prefer to add it only to our blogs pages… That's what it looks for me&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{{ 'blog-carousell.css' | asset_url | stylesheet_tag }}
&amp;lt;script src="{{ 'blog-carousell.js' | asset_url }}" defer="defer"&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.If you want to put a gallery in your blog post, remember to include an "alt" attribute for your images. The "alt" attribute should end with 'gallery {id}'. The "id" can be a number between 01 and 15 (leading zeros are needed).&lt;/p&gt;

&lt;p&gt;For example, let's say I have a few galleries within the same post. The images for the first gallery would have "alt" attributes like 'First Beef image, gallery 01' and 'Another Beef image, gallery 01'. Meanwhile, the images in another gallery would have "alt" attributes like 'Pork, gallery 02' and 'Pork, gallery 02'.&lt;/p&gt;

&lt;h1&gt;
  
  
  How it works
&lt;/h1&gt;

&lt;p&gt;Javascript file tries to group all images presented on the page based on alt attribute. Then it creates required dom elements and attach even handlers. &lt;/p&gt;

&lt;h1&gt;
  
  
  Demo
&lt;/h1&gt;

&lt;p&gt;The demo could be found here &lt;a href="https://www.singaporewinedelivery.com/blogs/news/best-wine-bars-in-singapore" rel="noopener noreferrer"&gt;Wine bars in Singapore&lt;/a&gt;&lt;/p&gt;

</description>
      <category>shopify</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
