<?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 Imran Sayed on Medium]]></title>
        <description><![CDATA[Stories by Imran Sayed on Medium]]></description>
        <link>https://medium.com/@imranhsayed?source=rss-bb850585be4f------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*SYS_EuUD-JKpTprs.jpg</url>
            <title>Stories by Imran Sayed on Medium</title>
            <link>https://medium.com/@imranhsayed?source=rss-bb850585be4f------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 07 Apr 2026 04:17:17 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@imranhsayed/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[How to Book the Best Dummy Flight Ticket for Visa Applications & Onward Travel | Complete Guide &…]]></title>
            <link>https://imranhsayed.medium.com/how-to-book-the-best-dummy-flight-ticket-for-visa-applications-onward-travel-bestonwardticket-100e4f32be90?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/100e4f32be90</guid>
            <category><![CDATA[best-onward-ticket]]></category>
            <category><![CDATA[dummy-ticket]]></category>
            <category><![CDATA[dummy-flight-ticket]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Mon, 09 Jun 2025 18:13:42 GMT</pubDate>
            <atom:updated>2025-06-09T18:14:45.027Z</atom:updated>
            <content:encoded><![CDATA[<h3>How to Book the Best Dummy Flight Ticket for Visa Applications &amp; Onward Travel | Complete Guide &amp; Review of BestOnwardTicket</h3><p>Traveling internationally often involves more than just packing your bags and booking your hotel. One major challenge travelers face — especially those applying for visas — is the requirement to show proof of <strong>onward travel</strong> or a <strong>return ticket</strong>. But what if you haven’t finalized your plans yet? Or you’re not ready to commit to an expensive flight just for a visa application?</p><p>That’s where <strong>dummy flight tickets</strong> come in.</p><p>In this comprehensive blog post, I’ll walk you through everything you need to know about dummy tickets — what they are, why they’re useful, when you need one, and most importantly, how to <strong>secure a legitimate and fast dummy flight reservation</strong> through a trusted provider: <strong>BestOnwardTicket.com</strong>.</p><p>I’ve personally used this service and can vouch for its reliability and speed. Whether you’re a digital nomad, backpacker, or business traveler, this guide is for you!</p><p>👉 <a href="https://bestonwardticket.com/?ref=169"><strong>Click here to get your ticket from BestOnwardTicket</strong></a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F7SzuGo8BwJ8&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D7SzuGo8BwJ8&amp;image=http%3A%2F%2Fi.ytimg.com%2Fvi%2F7SzuGo8BwJ8%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/1cbe16a4655f926423fd2fec2c6d75e1/href">https://medium.com/media/1cbe16a4655f926423fd2fec2c6d75e1/href</a></iframe><h3>🛫 What Is a Dummy Flight Ticket?</h3><p>A <strong>dummy flight ticket</strong> (also known as a flight reservation or itinerary) is a <strong>temporary, hold-only airline booking</strong> that looks exactly like a regular flight ticket. It includes your name, travel dates, departure and destination airports, and a verifiable PNR (Passenger Name Record).</p><p>However, unlike a paid ticket, a dummy ticket is not actually paid in full and isn’t meant to be used for travel. It’s intended to satisfy administrative requirements, such as:</p><ul><li><strong>Visa applications</strong></li><li><strong>Immigration verification</strong></li><li><strong>Airport security checks</strong></li><li><strong>Travel insurance claims</strong></li><li><strong>Proof of return/onward travel</strong></li></ul><p>These are not illegal or fake — they are real, temporary reservations made in your name, valid for a short time (usually 24–72 hours).</p><h3>🌍 Why Do You Need a Dummy Flight Ticket?</h3><p>There are several situations where a dummy ticket becomes essential:</p><h3>✈️ 1. Visa Applications</h3><p>Most embassies and consulates want to see a round-trip or onward flight reservation as part of your visa documentation. However, buying a full-price ticket before knowing if your visa will be approved can be risky and expensive.</p><p>With a dummy ticket, you can provide the necessary travel document without committing to a purchase.</p><h3>🧳 2. Proof of Onward Travel</h3><p>Some countries — especially in Southeast Asia, Latin America, and Africa — require proof that you’ll be leaving the country before your visa expires. Airlines may deny boarding if you can’t show this proof at check-in.</p><p>Dummy tickets help avoid this problem, giving you a temporary itinerary that proves you plan to exit the country.</p><h3>🛂 3. Immigration Requirements</h3><p>Even if you’re visiting a country visa-free, immigration officials might ask for evidence of your travel plans. A verifiable dummy ticket serves as a perfect solution.</p><h3>💼 4. Travel Insurance Claims</h3><p>In some cases, travel insurance providers request a travel itinerary before approving a claim. A dummy ticket can help in these instances.</p><h3>🚀 Why I Recommend BestOnwardTicket.com</h3><p>After trying several services over the years, I can confidently say that <strong>BestOnwardTicket</strong> stands out from the rest. Here’s why:</p><h3>✅ Fast and Reliable</h3><p>I received my dummy flight ticket in less than 10 minutes. Their system is fully automated and works 24/7.</p><h3>✅ Legit and Verifiable</h3><p>The ticket includes a real <strong>PNR number</strong> that you can verify directly on the airline’s website. That’s critical when dealing with embassies or strict immigration checks.</p><h3>✅ Excellent Customer Support</h3><p>Their support team is prompt, polite, and helpful. I had a few questions during my first purchase, and their team resolved everything in minutes.</p><h3>✅ Affordable Prices</h3><p>At just a few dollars per ticket, it’s much cheaper than buying a refundable flight. And definitely worth the peace of mind.</p><h3>✅ No Risk of Losing Money</h3><p>Unlike actual tickets that might cost hundreds of dollars, there’s no risk involved. You only pay a small service fee for the temporary reservation.</p><p>👉 <strong>Try it now at </strong><a href="https://bestonwardticket.com/?ref=169"><strong>BestOnwardTicket.com</strong></a></p><h3>🛠️ How to Book a Dummy Flight Ticket: Step-by-Step Guide</h3><p>Booking a dummy ticket with BestOnwardTicket is simple. Here’s a step-by-step guide:</p><h3>1️⃣ Visit the Website</h3><p>Go to <a href="https://bestonwardticket.com/?ref=169">https://bestonwardticket.com/?ref=169</a></p><h3>2️⃣ Enter Travel Details</h3><p>Fill in basic travel information:</p><ul><li>Departure city</li><li>Destination city</li><li>Travel date</li><li>Your full name</li></ul><h3>3️⃣ Make Payment</h3><p>Pay using a credit or debit card. Prices typically start around $12 USD.</p><h3>4️⃣ Receive Your Ticket</h3><p>Within minutes, you’ll receive your flight reservation via email in PDF format. The PNR number can be verified on the airline’s official site.</p><h3>5️⃣ Submit for Visa or Immigration</h3><p>Use the ticket as part of your visa application, check-in process, or for proof of onward travel.</p><h3>📌 Features to Look for in a Dummy Ticket Provider</h3><p>Here’s what you should expect from a professional dummy ticket service:</p><p>Feature BestOnwardTicket Offers Verifiable PNR ✅ Email Delivery ✅ Fast Processing (within 10 mins) ✅ 24/7 Support ✅ Trusted by Thousands of Travelers ✅ Flexible Travel Dates ✅ Major Airlines Covered ✅</p><h3>🧭 Who Should Use Dummy Tickets?</h3><h3>🎒 Backpackers &amp; Digital Nomads</h3><p>Perfect for spontaneous travelers who don’t have a fixed return plan but still need to satisfy immigration or visa requirements.</p><h3>👨‍💼 Business Travelers</h3><p>Save your company from spending on fully refundable tickets when only a temporary itinerary is needed.</p><h3>🧕 First-Time Visa Applicants</h3><p>Get peace of mind knowing you won’t lose hundreds of dollars if your visa is rejected.</p><h3>✨ Budget Travelers</h3><p>Keep your travel plans flexible without paying upfront for expensive tickets.</p><h3>✈️ Airline Examples</h3><p>BestOnwardTicket covers all major international airlines, including:</p><ul><li>Emirates</li><li>Qatar Airways</li><li>Lufthansa</li><li>Air India</li><li>Etihad</li><li>Turkish Airlines</li><li>British Airways</li><li>Singapore Airlines</li></ul><p>Each ticket you receive will come with a real airline reservation number that can be cross-checked.</p><h3>💡 Pro Tips for Using Dummy Tickets</h3><ul><li><strong>Use the ticket within 24–72 hours</strong> — These reservations expire quickly, so use them for immediate visa submissions or travel verification.</li><li><strong>Match your hotel booking and travel insurance dates</strong> to the dummy ticket for a cohesive application.</li><li><strong>Avoid using free fake ticket generators</strong> — These often result in visa rejections and may be flagged by embassies.</li><li><strong>Double-check the airline</strong> if you plan to verify the PNR on their website.</li></ul><h3>🚫 What NOT to Do with a Dummy Ticket</h3><ul><li>❌ Don’t attempt to board a flight using a dummy ticket — it’s not a paid booking.</li><li>❌ Don’t present an expired dummy ticket.</li><li>❌ Don’t alter the ticket manually — tampering with documents can lead to visa denial or legal trouble.</li></ul><h3>📚 Real-Life Scenarios</h3><h3>Example 1: Student Visa for France</h3><p>Sophie needed to show a flight reservation as part of her French student visa. Unsure about her semester dates, she used a dummy ticket and later booked a real one after getting her visa.</p><h3>Example 2: Onward Travel in Thailand</h3><p>Alex, a digital nomad, flew into Bangkok without a return ticket. Immigration demanded proof of onward travel. He quickly purchased a dummy ticket on his phone from BestOnwardTicket and was cleared in minutes.</p><h3>📈 Growing Need for Dummy Tickets</h3><p>With more countries tightening visa requirements and immigration policies, dummy tickets are becoming a must-have for travelers. According to recent data:</p><ul><li>Over 60% of visa applications require travel itineraries</li><li>1 in 5 travelers face issues due to lack of onward travel proof</li><li>Airlines can refuse boarding without return ticket proof — even in visa-free countries</li></ul><p>Having a legitimate dummy ticket ready can prevent delays, cancellations, and even deportation.</p><h3>🧾 Final Thoughts</h3><p>A dummy ticket may seem like a small piece of paper, but it can be the key to unlocking your next international adventure. Whether you’re applying for a visa, meeting immigration requirements, or simply buying yourself time before booking a real flight — <strong>BestOnwardTicket.com</strong> is the most efficient and trustworthy solution I’ve found.</p><p>I’ve used it, tested it, and now I’m recommending it. Their service is professional, fast, and 100% legit.</p><p>👉 <a href="https://bestonwardticket.com/?ref=169">Book your dummy flight ticket now</a></p><h3>🧭 Summary</h3><ul><li>✅ Dummy tickets are real, verifiable reservations (not paid in full)</li><li>✅ Ideal for visa applications and proof of onward travel</li><li>✅ BestOnwardTicket.com is fast, affordable, and legit</li><li>✅ Avoid scams and unreliable fake ticket generators</li><li>✅ Use dummy tickets responsibly and only for their intended purpose</li></ul><h3>📺 Watch the Full Video</h3><p>Check out my detailed YouTube review where I walk you through the booking process step-by-step.</p><p>🔗 Watch the video</p><h3>🙌 If This Helped You…</h3><p>Please <strong>LIKE</strong>, <strong>COMMENT</strong>, and <strong>SUBSCRIBE</strong> to my <a href="https://www.youtube.com/watch?v=7SzuGo8BwJ8">YouTube</a> channel. I post weekly tips on budget travel, visa hacks, and digital nomad lifestyle.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=100e4f32be90" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Apply for a Schengen Tourist Visa from Canada  | Step-by-Step Guide for Students | VFS…]]></title>
            <link>https://imranhsayed.medium.com/how-to-apply-for-a-schengen-tourist-visa-from-canada-step-by-step-guide-for-students-vfs-4a9f9a941c6e?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/4a9f9a941c6e</guid>
            <category><![CDATA[from-canada-to-france]]></category>
            <category><![CDATA[toronto]]></category>
            <category><![CDATA[schengen-visa]]></category>
            <category><![CDATA[vfsglobal]]></category>
            <category><![CDATA[appointment]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Sat, 08 Feb 2025 07:05:26 GMT</pubDate>
            <atom:updated>2025-02-08T07:07:44.450Z</atom:updated>
            <content:encoded><![CDATA[<h3>How to Apply for a Schengen Tourist Visa from Canada 🇨🇦 | Step-by-Step Guide for Students | VFS Canada</h3><p><strong>How to Apply for a Schengen Tourist Visa from Canada: A Step-by-Step Guide for Students</strong></p><p>If you’re a student in Canada planning a trip to Europe, you’ll need a <strong>Schengen Tourist Visa</strong> to explore the beautiful destinations across 27 European countries. This guide will walk you through the entire application process, from booking an appointment with <strong>VFS Global Canada</strong> to submitting your documents and understanding visa fees.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FEZmYoQLF9jw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DEZmYoQLF9jw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FEZmYoQLF9jw%2Fhqdefault.jpg&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/7a82d9596d57e4f5ec389571c9ffa6cc/href">https://medium.com/media/7a82d9596d57e4f5ec389571c9ffa6cc/href</a></iframe><h3>Step 1: Determine Your Entry Country</h3><p>The Schengen Visa allows you to travel across multiple European countries. However, you must apply through the consulate of the country you’ll be entering first or where you’ll spend the most time. In this guide, we’ll focus on applying through <strong>France</strong>, which is a popular choice for Canadian students.</p><h3>Step 2: Gather the Required Documents</h3><p>Before applying, make sure you have the following documents ready:</p><p>✅ <strong>Completed Schengen Visa Application Form</strong> — Available on the official VFS Global website. ✅ <strong>Valid Passport</strong> — Must be valid for at least three months beyond your planned departure from the Schengen Area. ✅ <strong>Canadian Study Permit &amp; Visa</strong> — Proof of your legal status in Canada. ✅ <strong>Proof of Travel</strong> — Round-trip flight reservations. ✅ <strong>Travel Insurance</strong> — Coverage of at least €30,000 for medical emergencies. ✅ <strong>Accommodation Proof</strong> — Hotel bookings, Airbnb reservations, or a letter of invitation from a host. ✅ <strong>Financial Proof</strong> — Bank statements showing you can financially support yourself during your stay. ✅ <strong>Cover Letter</strong> — Explaining your travel plans and purpose of visit. ✅ <strong>Student Verification</strong> — A letter from your university confirming your enrollment.</p><h3>Step 3: Book an Appointment with VFS Global</h3><p>To apply for a Schengen Visa, you must book an appointment at one of the <strong>VFS Global</strong> centers in Canada. These centers handle visa applications on behalf of European consulates.</p><p>📍 <strong>VFS Global Locations in Canada:</strong></p><ul><li><strong>Toronto</strong></li><li><strong>Ottawa</strong></li><li><strong>Montreal</strong></li><li><strong>Vancouver</strong></li></ul><p>To book an appointment:</p><ol><li>Visit the [VFS Global Canada website](Insert link).</li><li>Select <strong>France</strong> as your Schengen Visa destination.</li><li>Choose the appropriate visa type (Tourist Visa).</li><li>Select a convenient <strong>VFS location</strong> and available date.</li><li>Pay the <strong>appointment fee</strong> (if applicable).</li></ol><h3>Step 4: Submit Your Application</h3><p>On the day of your appointment, visit the <strong>VFS Global center</strong> with all your documents. You may also need to provide <strong>biometric data (fingerprints and photo)</strong> if it’s your first time applying for a Schengen Visa.</p><p>After submitting your documents, VFS Global will forward your application to the French consulate for processing.</p><h3>Step 5: Pay the Visa &amp; Processing Fees</h3><p>The visa application fee for a <strong>Schengen Tourist Visa</strong> is <strong>€90 (~$135 CAD)</strong>. Additionally, you may need to pay a <strong>VFS service fee</strong>, which varies depending on the center.</p><p><strong>Payment Methods:</strong> ✔ Debit/Credit card (Accepted at most VFS centers) ✔ Bank draft or money order (Check specific center requirements)</p><h3>Step 6: Track Your Application &amp; Wait for Approval</h3><p>Processing times for a <strong>Schengen Visa</strong> can take <strong>15 to 30 days</strong>, depending on the volume of applications. You can track your application status on the <strong>VFS Global</strong> website using your reference number.</p><p>Once your visa is approved, you will receive your <strong>passport with the visa stamp</strong>, allowing you to travel to <strong>France and other Schengen countries</strong>!</p><h3>Final Tips for a Successful Application</h3><p>✔ <strong>Apply at least 1–2 months before your trip</strong> to avoid last-minute delays. ✔ <strong>Ensure your documents are complete and accurate</strong> to prevent rejection. ✔ <strong>Be honest in your cover letter</strong> and interview if required. ✔ <strong>Check for additional requirements</strong> based on your nationality (some countries may have extra conditions).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9A7GcQWCWu-XQLOLeVpl8Q.png" /><figcaption>How to Apply Schengen Visa from Canada</figcaption></figure><h3>Conclusion</h3><p>Applying for a <strong>Schengen Tourist Visa from Canada</strong> may seem complicated, but with proper preparation, the process can be smooth and stress-free. Follow this guide to book your <strong>VFS Global appointment, gather your documents, and submit your application hassle-free</strong>. Soon, you’ll be on your way to an amazing European adventure! 🇫🇷✈️</p><p>📢 <strong>Need more travel tips?</strong> Stay tuned for more guides on visas, travel planning, and student life in Canada!</p><p>📌 Useful Links &amp; Resources: [Official VFS Global Canada Website] <a href="https://visa.vfsglobal.com/can/en/fra/login">https://visa.vfsglobal.com/can/en/fra/login</a> [Schengen Visa Application Form] <a href="https://application-form.france-visas.gouv.fr/">https://application-form.france-visas.gouv.fr/</a> <a href="https://france-visas.gouv.fr/en/canada">https://france-visas.gouv.fr/en/canada</a> <a href="https://france-visas.gouv.fr/en/web/france-visas/frequently-asked-questions">https://france-visas.gouv.fr/en/web/france-visas/frequently-asked-questions</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a9f9a941c6e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Exploring the Heart of Indian Cuisine in Winnipeg: An Interview with Poonam Vatsyayan, Owner of…]]></title>
            <link>https://imranhsayed.medium.com/exploring-the-heart-of-indian-cuisine-in-winnipeg-an-interview-with-poonam-vatsvayan-owner-of-72173f2f152e?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/72173f2f152e</guid>
            <category><![CDATA[indian-restaurant]]></category>
            <category><![CDATA[bread-and-biryani]]></category>
            <category><![CDATA[affordable]]></category>
            <category><![CDATA[winnipeg]]></category>
            <category><![CDATA[authentic-foods]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Thu, 14 Nov 2024 00:32:06 GMT</pubDate>
            <atom:updated>2024-11-14T04:42:35.732Z</atom:updated>
            <content:encoded><![CDATA[<h3>Exploring the Heart of Indian Cuisine in Winnipeg: An Interview with Poonam Vatsyayan, Owner of Bread and Biryani</h3><p>In the bustling core of Winnipeg’s downtown, <em>Bread and Biryani</em> stands out as a beacon of authentic Indian cuisine. Founded in 2021 by Poonam Vatsyayan, the restaurant has rapidly become a favorite among locals and newcomers alike, offering traditional dishes like biryani, samosas, and freshly baked naan that are not only flavorful but affordable. I had the opportunity to speak with Mrs. Vatsyayan to learn more about the story behind her restaurant, the unique challenges she faces, and the principles that drive her business forward.</p><h3>Starting with a Dream and a Little Help from Friends</h3><p>Mrs. Vatsyayan’s journey into the restaurant business began with encouragement from a close friend, Mr. Jagdev Singh, who has established several successful restaurants across Canada. With her passion for cooking and a desire to bring Indian flavors to Winnipeg, she opened <em>Bread and Biryani</em>, aiming to provide an authentic dining experience that would appeal to both the Indian diaspora and those looking to explore new tastes. Located within walking distance of the University of Winnipeg, the restaurant has attracted a broad customer base, including students, families, and tourists, all eager to savor the rich tastes of India.</p><h3>Daily Operations and Unique Challenges</h3><p>Running a restaurant is no small feat, and Mrs. Vatsyayan’s day begins with meal preparation tasks like making curries, dough, and filling for samosas. Some meats are marinated and thawed the day before to save time and ensure the food is ready for the day’s service. She also oversees the staff, manages deliveries, and handles customer interactions.</p><p>One of the biggest challenges she faces is finding skilled, trustworthy staff. The specialized nature of Indian cuisine demands a certain expertise, and hiring suitable candidates locally has been difficult, sometimes requiring her to consider recruiting from abroad. Additionally, being situated in a central urban area brings its own difficulties; for instance, some patrons may feel uneasy due to the presence of individuals under the influence in the vicinity, which can affect families’ willingness to visit.</p><h3>Thriving in Winnipeg’s Business Environment</h3><p>Operating in Canada comes with both opportunities and obstacles, and Mrs. Vatsyayan has felt the impact of the country’s changing economic landscape. For instance, her restaurant relies on ingredients imported from neighboring countries, and global conflicts have led to rising costs and reduced freshness in available produce. While many businesses would respond by raising prices, Mrs. Vatsyayan’s focus is on customer satisfaction; she has chosen to absorb these additional costs to keep her meals affordable.</p><p>This choice not only strengthens customer loyalty but also shows her dedication to making <em>Bread and Biryani</em> a community-friendly establishment where authentic food is accessible to everyone, regardless of economic conditions.</p><h3>Success Through Hygiene, Ambiance, and Location</h3><p>The restaurant’s key to success lies in its values, with cleanliness at the top of the list. Hygiene is essential in the food industry, and Mrs. Vatsyayan ensures her staff strictly follows sanitation protocols. Recently, the restaurant underwent renovations to improve its ambiance, creating a warm and inviting space. Its location in downtown Winnipeg gives it visibility and accessibility, which, combined with its proximity to the university, makes it a popular choice for students looking for affordable, nutritious meals close by.</p><h3>Staying Authentic to Meet Local Tastes</h3><p>In the age of fusion cuisine, <em>Bread and Biryani</em> stays true to its roots by maintaining an authentic East Indian taste, complete with spices and herbs known for their health benefits. Mrs. Vatsyayan describes her approach as “need creation” — by focusing on delivering quality, hygienic, and flavorful food, she meets customers’ demand for authentic Indian dishes. The unique flavors, combined with the nutritional value, keep patrons coming back.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*7ektpfpZckVDlANmjCqVaQ.jpeg" /></figure><h3>Standing Out in a Competitive Market</h3><p>The restaurant scene in Winnipeg is competitive, but Mrs. Vatsyayan has found her niche. Her emphasis on quality ingredients and consistency in flavor ensures that customers know what to expect each time they visit. Unlike some establishments that may fluctuate in taste, she meticulously measures ingredients to guarantee each dish tastes the same every day. Coupled with affordable pricing, this approach has helped her build a loyal customer base that appreciates quality and value.</p><h3>Embracing Technology and Building a Positive Culture</h3><p>In an increasingly digital world, Mrs. Vatsyayan has harnessed the power of technology to reach a broader audience. The restaurant uses platforms like TikTok for marketing and partners with food delivery apps like DoorDash, UberEats, and SkipTheDishes. These services have not only increased the restaurant’s visibility but have also made it easier for customers to enjoy their favorite dishes from the comfort of home.</p><p>As for her team, Mrs. Vatsyayan prioritizes creating a positive work environment. She offers job security, pays fair wages, and treats her staff with respect, which has cultivated a motivated, happy team. Her philosophy is simple: when employees feel valued and respected, they are more invested in the success of the business.</p><h3>Looking Ahead: The Future of Bread and Biryani</h3><p>With her eyes on the future, Mrs. Vatsyayan envisions opening two more branches, ultimately establishing a franchise model. Her dedication to quality, affordability, and authenticity has laid a strong foundation, and expanding within Winnipeg and beyond seems like a natural progression. Her dream is to bring the flavors of <em>Bread and Biryani</em> to more communities, spreading the joy of Indian cuisine across Canada.</p><h3>Final Thoughts</h3><p>Interviewing Mrs. Poonam Vatsyayan revealed a blend of passion, resilience, and community commitment. Her restaurant, <em>Bread and Biryani</em>, isn’t just a business; it’s a reflection of her values and love for authentic Indian food. In an industry where economic challenges and competitive pressures abound, her focus on ethics, quality, and customer satisfaction makes her a standout leader. Her story is an inspiring reminder that true success comes not only from profits but from a commitment to making a positive impact on customers and the community.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=72173f2f152e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Setup And Run Cypress Tests With Your WordPress Plugin]]></title>
            <link>https://imranhsayed.medium.com/setup-and-run-cypress-tests-with-your-wordpress-plugin-95991200e69c?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/95991200e69c</guid>
            <category><![CDATA[test]]></category>
            <category><![CDATA[wordpress]]></category>
            <category><![CDATA[e2e-testing]]></category>
            <category><![CDATA[cypress]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Mon, 05 Sep 2022 14:33:47 GMT</pubDate>
            <atom:updated>2022-09-05T14:33:47.771Z</atom:updated>
            <content:encoded><![CDATA[<p>In this blog, we will learn how to setup and run Cypress test with your WordPress plugin.</p><p><strong>Source Code</strong>: (for smart people 😉) <a href="https://github.com/imranhsayed/aquila-features/pull/7">https://github.com/imranhsayed/aquila-features/pull/7</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Kl3KsZlQ8DfvezXOlxmWLQ.png" /></figure><p>In this blog, we will learn how to setup and run Cypress test with your WordPress plugin.</p><p>Step 1: Install Cypress( Assuming you already have a package.json file in your project, else run npm init first.</p><pre>npm install cypress --save-dev</pre><p>This will install cypress locally in node_modules of your project.</p><p>Step 2: Add the cypress:open script in your package.json file</p><pre>&quot;scripts&quot;: {<br>		&quot;cypress:open&quot;: &quot;node_modules/.bin/cypress open&quot;<br>	},</pre><p>Step 3: Now run `npm run cypress:open` to open cypress . This will open cypress application in your browser and also add cypress.config.js and cypress folder with some default tests in the root of your project.</p><pre>npm run cypress:open</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*qKesDgQr_IOJPJ5a" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*vYsJvPF3VnCWe7YD" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/620/0*cUyHRWHza6FiI5S4" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/512/0*suplKaSAfL6-RSpP" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/0*GZkG2ghrVO9ylTgK" /></figure><p>Let’s choose our options and select e2e( end to end ) testing .</p><p>Step 4 : Add your base(root) URL of your WordPress site and username and password in cypress.config.js ( Note This is only for testing purposes, we should not push our credentials publicly on Github etc )</p><pre>const { defineConfig } = require(&quot;cypress&quot;);</pre><pre>module.exports = defineConfig({<br>	env: {<br>		wpUser: &#39;root&#39;,<br>		wpPassword: &#39;root&#39;,<br>	},<br>  e2e: {<br>	  baseUrl: &#39;http://localhost:8888&#39;,<br>    setupNodeEvents(on, config) {<br>      // implement node event listeners here<br>    },<br>  },<br>});</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/479/0*_imlviDc2MHSvgOQ" /></figure><p>You can also create your own test file called admin-login.cy.js in cypress/e2e folder, as shown below:</p><pre>describe( &#39;Run a pull&#39;, function() {<br>	// Go to WordPress login page and login.<br>	beforeEach( function() {<br>		cy.visit( &#39;/wp-login.php&#39; );<br>		cy.wait( 1000 );<br>		cy.get( &#39;#user_login&#39; ).type( Cypress.env( &quot;wpUser&quot; ) );<br>		cy.get( &#39;#user_pass&#39; ).type( Cypress.env( &quot;wpPassword&quot; ) );<br>		cy.get( &#39;#wp-submit&#39; ).click();<br>	} );<br>	<br>	it( &#39;can run a pull&#39;, function() {<br>		cy.wait( 2000 );<br>		cy.url().should(&#39;eq&#39;, &#39;http://localhost:8888/wp-admin/&#39;);<br>	} );<br>});</pre><p>Now let’s run this test by clicking on the admin-login.cy.js</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/0*ULpuCh7zwxVV8H4p" /></figure><p>Congratulations the login test is successful.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/0*ip7dB_CBiNqH5JXf" /></figure><p><a href="https://github.com/imranhsayed/aquila-features/pull/7">https://github.com/imranhsayed/aquila-features/pull/7</a></p><p>For more details check <a href="https://docs.cypress.io/guides/getting-started/">https://docs.cypress.io/guides/getting-started/</a></p><p>That’s all folks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=95991200e69c" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Check If A User Or Author Has Avatar In WordPress And Set User Image With First Letter As Default]]></title>
            <link>https://imranhsayed.medium.com/check-if-a-user-or-author-has-avatar-in-wordpress-and-set-user-image-first-letter-as-default-7212f7a83106?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/7212f7a83106</guid>
            <category><![CDATA[avatar]]></category>
            <category><![CDATA[wordpress]]></category>
            <category><![CDATA[authors]]></category>
            <category><![CDATA[image]]></category>
            <category><![CDATA[has-avatar]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Mon, 27 Dec 2021 16:27:43 GMT</pubDate>
            <atom:updated>2022-03-13T05:12:24.036Z</atom:updated>
            <content:encoded><![CDATA[<p>Sometimes we do not want WordPress to display the default avatar. There isn’t a WP core function to check that. So we will create one. We will also learn how to add the first letters of the user’s first name and last name as a fallback avatar picture using JavaScript.</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2F0OexKVbbISY%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D0OexKVbbISY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2F0OexKVbbISY%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/3fadc3b85a6c76cb93441b89de671845/href">https://medium.com/media/3fadc3b85a6c76cb93441b89de671845/href</a></iframe><h3>Steps to achieve the goal:</h3><p>There are two things we need to check, If the user has uploaded the gravatar from:<br>1. <em>WP Dashboard (using </em><a href="https://wordpress.org/plugins/wp-user-avatars/"><em>wp-user-avatar plugin</em></a><em>)</em>, or<br>2. <em>Gravatar site.</em><br> <br>If any of the above conditions is true, the user has valid gravatar,<br>and the function will return true.</p><p>1. <em>For Scenario 1: Upload from WP Dashboard:</em><br> We check if the query args are present or not.</p><p>2. <em>For Scenario 2: Upload on Gravatar site:</em><br>When constructing the URL, use the parameter d=404.<br>This will cause Gravatar to return a 404 error rather than an image if the user hasn’t set a picture.</p><h3>Create Custom has_avatar function</h3><p>Let’s create a function and add it in functions.php</p><pre><em>/**<br> * Checks to see if the specified user id has a uploaded the image via wp_admin.<br> *<br> * </em><strong><em>@return </em></strong><em>bool  Whether or not the user has a gravatar<br> */<br></em>function is_uploaded_via_wp_admin( $gravatar_url ) {<br><br>   $parsed_url   = wp_parse_url( $gravatar_url );<br><br>   $query_args = ! empty( $parsed_url[&#39;query&#39;] ) ? $parsed_url[&#39;query&#39;] : &#39;&#39;;<br><br>   // If query args is empty means, user has uploaded gravatar.<br>   return empty( $query_args );<br><br>}</pre><p>Let’s print_r($parsed_url) and see the difference in the URL, when an avatar is uploaded using <a href="https://wordpress.org/plugins/wp-user-avatars/">plugin</a>, and when it’s not.</p><p><strong>Avatar uploaded from admin:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*enOantLvjpmSgvRjRjd0EQ.png" /></figure><p><strong>Avatar not uploaded:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*h0QDl9I-tkA1ZX68Pd9yaw.png" /></figure><p>Notice there is a query key available when an avatar is not uploaded.</p><p>Now let’s create another has_gravatar() function which in turn calls the is_uploaded_via_wp_admin() function.</p><pre>function has_gravatar( $user_email ) {<br><br>   $gravatar_url = get_avatar_url( $user_email );</pre><pre>// 1. Check if uploaded from WP Dashboard.<br>   if ( is_uploaded_via_wp_admin( $gravatar_url ) ) {<br>      return true;<br>   }</pre><pre>   // 2. Check if uploaded from gravatar site by adding 404 in the url query param <br>   $gravatar_url = sprintf( &#39;%s&amp;d=404&#39;, $gravatar_url );<br><br>   // Make a request to $gravatar_url and get the header<br>   $headers = @get_headers( $gravatar_url );<br><br>   // If request status is 200, which means user has uploaded the avatar on gravatar ste<br>   return preg_match( &quot;|200|&quot;, $headers[0] );<br>}</pre><p><strong>Logic:</strong> When constructing the URL, we add the parameter d=404. This causes gravatar to return a 404 error status rather than an image with 200 status if the user hasn’t set a picture.</p><p>Notice when the user has uploaded the gravatar on the gravatar site, the status is 200 vs when it’s not it’s 404</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LAKMwn-GhHeCkPP1kHKzCg.png" /><figcaption>Gravatar uploaded</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e5ozbngbxsOu6GXzL2rpZQ.png" /><figcaption>Gravatar not uploaded</figcaption></figure><h4>Using has_avatar()</h4><p>Now you can use this function to conditionally render the gravatar. In author.php archive page.</p><pre>$author_email = get_the_author_meta( &#39;user_email&#39; );<br>$has_avatar = has_gravatar( $author_email );<br>$avatar = get_avatar( $author_email, 251, &#39;&#39;, &#39;&#39;, [&#39;class&#39; =&gt; &#39;w-251px h-251px object-cover rounded-full&#39;] );</pre><pre>&lt;?php<br>   if ( !empty( $has_avatar ) ) {<br>      echo wp_kses_post($avatar);<br>   } else {<br>      printf(<br>            &#39;&lt;span id=&quot;author-firstname&quot; class=&quot;hidden&quot;&gt;%1$s&lt;/span&gt;&lt;span id=&quot;author-lastname&quot; class=&quot;hidden&quot;&gt;%2$s&lt;/span&gt;&lt;div id=&quot;author-profile-img&quot; class=&quot;w-251px h-251px object-cover rounded-full bg-brand-yellow relative&quot;&gt;&lt;span class=&quot;text-6xl font-lato-bold tracking-0.5px text-white inset-center&quot;&gt;&lt;/span&gt;&lt;/div&gt;&#39;,<br>         esc_html( get_the_author_meta( &#39;first_name&#39;, $author_id ) ),<br>         esc_html( get_the_author_meta( &#39;last_name&#39;, $author_id ) )<br>      );<br>   }<br>?&gt;</pre><p>You can also add JavaScript to show the initial two letters from JS if the author&#39;s gravatar is not present like so:</p><pre>( function( $ ) {<br>   class Author {<br>      constructor() {<br>         this.authorProfileImgContainer = $( &#39;#author-profile-img span&#39; );<br>         this.authorFirstNameText = $( &#39;#author-firstname&#39; ).text();<br>         this.authorLastNameText = $( &#39;#author-lastname&#39; ).text();<br>         <br>         this.init();<br>      }<br>      <br>      init() {<br>         if ( ! this.authorProfileImgContainer.length ) {<br>            return null;<br>         }<br>         <br>         let initials = this.authorFirstNameText.charAt( 0 ) + this.authorLastNameText.charAt( 0 );<br>         initials = initials ? initials : &#39;A&#39;;<br>         <br>         // Set the text.<br>         this.authorProfileImgContainer.text( initials );<br>      }<br>      <br>   }<br>   <br>   new Author();<br>} )( jQuery );</pre><p>Display the initials of the author Emma Watson i.e ES, when gravatar is not present.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/674/1*vTsR3qKFsxBNsyscqg-bnQ.png" /></figure><p>That’s all folks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7212f7a83106" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding Offset With Limit To wp_get_archives for pagination.]]></title>
            <link>https://imranhsayed.medium.com/adding-offset-with-limit-to-wp-get-archives-for-pagination-6b511cf5a817?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/6b511cf5a817</guid>
            <category><![CDATA[limits]]></category>
            <category><![CDATA[offset]]></category>
            <category><![CDATA[wp-get-archives]]></category>
            <category><![CDATA[wordpress]]></category>
            <category><![CDATA[pagination]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Thu, 23 Dec 2021 14:17:23 GMT</pubDate>
            <atom:updated>2021-12-23T14:17:23.198Z</atom:updated>
            <content:encoded><![CDATA[<p>In this blog, we will learn about how to add the offset and the limit for pagination. In this example, we are showing this for monthly archives, but you can do it similarly for the daily and yearly as well.</p><pre>function get_custom_monthly_archives( $args = []) {<br><br>   global $wpdb, $wp_locale;<br><br>   $defaults = [<br>      &#39;type&#39;            =&gt; &#39;monthly&#39;,<br>      &#39;limit&#39;           =&gt; &#39;&#39;,<br>      &#39;offset&#39;          =&gt; &#39;&#39;,<br>      &#39;format&#39;          =&gt; &#39;html&#39;,<br>      &#39;before&#39;          =&gt; &#39;&#39;,<br>      &#39;after&#39;           =&gt; &#39;&#39;,<br>      &#39;show_post_count&#39; =&gt; false,<br>      &#39;echo&#39;            =&gt; 1,<br>      &#39;order&#39;           =&gt; &#39;DESC&#39;,<br>      &#39;post_type&#39;       =&gt; &#39;post&#39;,<br>      &#39;year&#39;            =&gt; get_query_var( &#39;year&#39; ),<br>      &#39;monthnum&#39;        =&gt; get_query_var( &#39;month&#39; ),<br>      &#39;day&#39;             =&gt; get_query_var( &#39;day&#39; ),<br>      &#39;w&#39;               =&gt; get_query_var( &#39;w&#39; ),<br>   ];<br><br>   $parsed_args = wp_parse_args( $args, $defaults );<br><br>   $output = &#39;&#39;;<br>   $last_changed = wp_cache_get_last_changed( &#39;posts&#39; );<br>   $join = apply_filters( &#39;getarchives_join&#39;, &#39;&#39;, $parsed_args );<br>   $sql_where = $wpdb-&gt;prepare( &quot;WHERE post_type = %s AND post_status = &#39;publish&#39;&quot;, $parsed_args[&#39;post_type&#39;] );<br>   $where = apply_filters( &#39;getarchives_where&#39;, $sql_where, $parsed_args );<br><br>   $order = $parsed_args[&#39;order&#39;];<br><br>   if ( ! empty( $parsed_args[&#39;limit&#39;] ) &amp;&amp; empty( $parsed_args[&#39;offset&#39;] ) ) {<br>      $limit = sprintf( &#39; LIMIT %1$s&#39;, intval( $parsed_args[&#39;limit&#39;] ) );<br>   } elseif ( ! empty( $parsed_args[&#39;limit&#39;] ) &amp;&amp; ! empty( $parsed_args[&#39;offset&#39;] ) ) {<br>      $limit = sprintf( &#39; LIMIT %1$s,%2$s&#39;, intval( $parsed_args[&#39;offset&#39;] ), intval( $parsed_args[&#39;limit&#39;] ) );<br>   } else {<br>      $limit = &#39;&#39;;<br>   }<br><br>   $query   = &quot;SELECT YEAR(post_date) AS `year`, MONTH(post_date) AS `month`, count(ID) as posts FROM $wpdb-&gt;posts $join $where GROUP BY YEAR(post_date), MONTH(post_date) ORDER BY post_date $order $limit&quot;;<br>   $key     = md5( $query );<br>   $key     = &quot;wp_get_archives:$key:$last_changed&quot;;<br>   $results = wp_cache_get( $key, &#39;posts&#39; );<br><br>   if ( ! $results ) {<br>      $results = $wpdb-&gt;get_results( $query );<br>      wp_cache_set( $key, $results, &#39;posts&#39; );<br>   }<br>   if ( $results ) {<br>      $after = $parsed_args[&#39;after&#39;];<br>      foreach ( (array) $results as $result ) {<br>         $url = get_month_link( $result-&gt;year, $result-&gt;month );<br>         if ( &#39;post&#39; !== $parsed_args[&#39;post_type&#39;] ) {<br>            $url = add_query_arg( &#39;post_type&#39;, $parsed_args[&#39;post_type&#39;], $url );<br>         }<br>         /* translators: 1: Month name, 2: 4-digit year. */<br>         $text = sprintf( __( &#39;%1$s %2$d&#39; ), $wp_locale-&gt;get_month( $result-&gt;month ), $result-&gt;year );<br>         if ( $parsed_args[&#39;show_post_count&#39;] ) {<br>            $parsed_args[&#39;after&#39;] = &#39;&amp;nbsp;(&#39; . $result-&gt;posts . &#39;)&#39; . $after;<br>         }<br>         $selected = is_archive() &amp;&amp; (string) $parsed_args[&#39;year&#39;] === $result-&gt;year &amp;&amp; (string) $parsed_args[&#39;monthnum&#39;] === $result-&gt;month;<br>         $output  .= get_archives_link( $url, $text, $parsed_args[&#39;format&#39;], $parsed_args[&#39;before&#39;], $parsed_args[&#39;after&#39;], $selected );<br>      }<br>   }<br><br>   return $output;<br>}</pre><p>Using this function.</p><pre>get_custom_monthly_archives([&#39;limit&#39;=&gt; 1, &#39;offset&#39;=&gt;&#39;2&#39;]);</pre><p>That’s all folks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6b511cf5a817" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Create Custom Post Type Search Result Page In WordPress]]></title>
            <link>https://imranhsayed.medium.com/create-custom-post-type-search-result-page-in-wordpress-fe56966dcce1?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/fe56966dcce1</guid>
            <category><![CDATA[custom-post-types]]></category>
            <category><![CDATA[custom]]></category>
            <category><![CDATA[search]]></category>
            <category><![CDATA[query]]></category>
            <category><![CDATA[search-results]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Wed, 22 Dec 2021 12:01:27 GMT</pubDate>
            <atom:updated>2021-12-23T06:51:03.598Z</atom:updated>
            <content:encoded><![CDATA[<p>In this blog, we will learn about how to create a custom post-type search result page in WordPress.</p><p>We need to take the following steps:</p><ol><li>Create a custom search page template ( {custom-post-type}-search.php )</li><li>Load your template using ‘template_include’ filter</li><li>Create a custom search form template ( {custom-post-type}-searchform.php )</li></ol><h4>Step One — Custom Search Page Template</h4><p>Create a Custom search page template custom-post-type-search.php</p><pre>&lt;?php<br><em>/**<br> * Custom Post Type Search result page.<br> *<br> * </em><strong><em>@package </em></strong><em>Aquila<br> */</em></pre><pre>get_header();<br>global $wp_query;<br><br>?&gt;<br>&lt;div id=&quot;primary&quot;&gt;<br>   &lt;main id=&quot;main&quot; class=&quot;site-main mt-5 mb-14&quot; role=&quot;main&quot;&gt;<br>      &lt;div class=&quot;container&quot;&gt;<br>         &lt;header class=&quot;mb-5&quot;&gt;<br>            &lt;h1 class=&quot;page-title&quot;&gt;<br>               &lt;?php _e( &#39;Search results for&#39;, &#39;text-domain&#39; ); ?&gt;: &quot;&lt;?php the_search_query(); ?&gt;&quot;<br>            &lt;/h1&gt;<br>         &lt;/header&gt;<br><br>         &lt;?php if ( have_posts() ) { ?&gt;<br><br>            &lt;div class=&quot;grid md:grid-cols-3 border-1 border-brand-bright-grey&quot;&gt;<br><br>               &lt;?php while ( have_posts() ) {<br>                  the_post();<br><br>                  get_template_part( &#39;template-parts/common/article&#39; );<br><br>               } ?&gt;<br><br>            &lt;/div&gt;<br><br>            &lt;div class=&quot;search-results-post-navigation my-5&quot;&gt;<br>               &lt;?php<br>               the_posts_navigation();<br>               ?&gt;<br>            &lt;/div&gt;<br>         &lt;?php } else {<br>            get_template_part( &#39;template-parts/content&#39;, &#39;none&#39; );<br>         } ?&gt;<br><br>      &lt;/div&gt;<br>   &lt;/main&gt;<br>&lt;/div&gt;<br>&lt;?php get_footer(); ?&gt;</pre><h4>Step 2 — Load your template using ‘template_include’ filter</h4><p>Inside your functions.php</p><pre>namespace YourNameSpace;<br><br>function render_search_template( $template ) {<br>   global $wp_query;<br>   $post_type = get_query_var( &#39;post_type&#39; );<br><br>   if ( ! empty( $wp_query-&gt;is_search ) &amp;&amp; $post_type == &#39;custom-post-type-slug&#39;) {<br>      return locate_template( &#39;custom-post-type-search.php&#39; );  //  redirect to custom-post-type-search.php<br>   }<br><br>   return $template;<br>}<br><br>add_filter( &#39;template_include&#39;, <em>__NAMESPACE__ </em>. &#39;\\render_search_template&#39; );</pre><h4>Step 3 — Custom Search Form Template</h4><p>Create a Custom search form template template-parts/custom-post-type-searchform.php</p><pre>&lt;?php<br><em>/**<br> * Custom Post Type Search form<br> *<br> * </em><strong><em>@package </em></strong><em>Aquila<br> */<br><br></em>?&gt;<br><br>&lt;form role=&quot;search&quot; method=&quot;get&quot; id=&quot;searchform block&quot; class=&quot;search-form&quot; action=&quot;&lt;?php echo esc_url( home_url( &#39;/&#39; ) ); ?&gt;&quot; &gt;<br>   &lt;div class=&quot;relative&quot;&gt;<br>      &lt;label class=&quot;screen-reader-text&quot; for=&quot;s&quot;&gt;&lt;?php esc_html_e( &#39;Search for:&#39;, &#39;text-domain&#39; ); ?&gt;&lt;/label&gt;<br>      &lt;input id=&quot;search-field&quot; type=&quot;search&quot; class=&quot;search-field outline-none&quot; placeholder=&quot;&lt;?php esc_html_e( &#39;Search ...&#39;, &#39;text-domain&#39; ); ?&gt;&quot; value=&quot;&lt;?php echo esc_html( get_search_query() ); ?&gt;&quot; name=&quot;s&quot; /&gt;<br>      &lt;input type=&quot;hidden&quot; name=&quot;post_type&quot; value=&quot;custom-post-type-slug&quot; /&gt;<br>      &lt;button class=&quot;search-button cursor-pointer absolute right-0 top-0 bottom-0 m-auto py-5 px-4 ml-4&quot; type=&quot;submit&quot; id=&quot;searchsubmit&quot;&gt;<br>         &lt;span class=&quot;sr-only&quot;&gt;&lt;?php esc_html_e( &#39;Search&#39;, &#39;text-domain&#39; ); ?&gt;&lt;/span&gt;<br>         &lt;svg class=&quot;w-18px h-18px cursor-pointer&quot;&gt;<br>&lt;svg id=&quot;search-icon-grey&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;17.766&quot; height=&quot;17.738&quot; viewBox=&quot;0 0 17.766 17.738&quot;&gt;<br>   &lt;path id=&quot;Path_166&quot; data-name=&quot;Path 166&quot; d=&quot;M17.63,10.986A6.631,6.631,0,1,0,22.161,22.46l5.7,5.7a.222.222,0,0,0,.318-.311l-5.7-5.7A6.632,6.632,0,0,0,17.63,10.986Zm0,.442a6.189,6.189,0,1,1-6.188,6.189A6.185,6.185,0,0,1,17.63,11.428Z&quot; transform=&quot;translate(-10.75 -10.736)&quot; stroke=&quot;#000&quot; stroke-miterlimit=&quot;10&quot; stroke-width=&quot;0.5&quot;/&gt;<br>&lt;/svg&gt;<br>         &lt;/svg&gt;<br>      &lt;/button&gt;<br>   &lt;/div&gt;<br>&lt;/form&gt;</pre><p>The mainline to note in the above code is &lt;input type=”hidden” name=”post_type” value=”your-custom-post-type-slug” /&gt; This will add a query params <a href="http://wpr.local/?s=nov&amp;post_type=news-wire">post_type</a> in the URL, when the user clicks on the submit button like so : <a href="http://wpr.local/?s=nov&amp;post_type=news-wire">https://example.com/?s=nov&amp;post_type=</a>custom-post-type-slug</p><p>So when you print the $wpquery ( from global $wpquery ) in your custom search page template, it will set the post_typevalue in the query object and automatically fetch the results from that post type.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*X6AcAlzjptMQSv48xujj5Q.png" /></figure><p>Now wherever you need the search form, you can include this template using get_template_part()</p><h4>Bonus Tip</h4><p>If you want to exclude this custom post type from the search result of the default post type ‘post’. Add the following in your `searchform.php`</p><pre>&lt;input type=&quot;hidden&quot; name=&quot;post_type&quot; value=&quot;post&quot; /&gt;</pre><p>This will ensure it only shows the result of the post type post</p><p>That’s all folks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fe56966dcce1" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding Scroll To Top In WordPress Site]]></title>
            <link>https://imranhsayed.medium.com/adding-scroll-to-top-in-wordpress-site-5ce053a80fd0?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/5ce053a80fd0</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[animation]]></category>
            <category><![CDATA[wordpress]]></category>
            <category><![CDATA[scroll-to-top]]></category>
            <category><![CDATA[scrolltop]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Wed, 22 Dec 2021 08:09:41 GMT</pubDate>
            <atom:updated>2021-12-22T08:09:41.354Z</atom:updated>
            <content:encoded><![CDATA[<p>In this blog, we will learn about how to add a scroll to the top button in WordPress Site.</p><h4>Scroll To Top Button</h4><p>Add the scroll to top button in footer.php Note that some of the classes I am using are from <a href="https://tailwindcss.com/">tailwindcss</a></p><pre>&lt;div id=&quot;footer-wrapper&quot; class=&quot; text-white footer-wrapper&quot;&gt;<br>   &lt;footer id=&quot;colophon&quot; class=&quot;site-footerpt-50px pb-43px lg:pt-85px lg:pb-74px&quot;&gt;<br><br>   &lt;div class=&quot;back-to-top&quot;&gt;<br>      &lt;button id=&quot;back-to-top&quot;&gt;<br>&lt;svg class=&quot;w-6 h-6 transform -rotate-90&quot; id=&quot;icon-arrow-heavy&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;24&quot; height=&quot;24&quot; viewBox=&quot;0 0 24 24&quot;&gt;&lt;path d=&quot;M13 7v-6l11 11-11 11v-6h-13v-10z&quot;/&gt;<br>         &lt;/svg&gt;<br>         &lt;span&gt;&lt;?php esc_html_e( &#39;go to top&#39;, &#39;text-domain&#39; ); ?&gt;&lt;/span&gt;<br>      &lt;/button&gt;<br>   &lt;/div&gt;<br>&lt;/div&gt;&lt;!-- #footer-wrapper --&gt;<br>&lt;?php<br><br>wp_footer();<br>?&gt;<br>&lt;/body&gt;<br>&lt;/html&gt;</pre><h4>InViewPortAnimation</h4><p>Create a JS file called in-viewport-animation.js .</p><pre><strong><em>$ </em></strong>= jQuery;<br><br><strong><em>$</em></strong>.fn.extend( {<br>   getPath: function () {<br>      let path, node = this;<br>      while ( node.length ) {<br>         var realNode = node[0], name = realNode.nodeName;<br>         if ( ! name ) {<br>            break;<br>         }<br>         <br>         name = name.toLowerCase();<br>         <br>         let parent = node.parent();<br>         <br>         let sameTagSiblings = parent.children( name );<br>         if ( sameTagSiblings.length ) {<br>            let allSiblings = parent.children();<br>            let index = allSiblings.index( realNode ) + 1;<br>            if ( index &gt; 1 ) {<br>               name += &#39;:nth-child(&#39; + index + &#39;)&#39;;<br>            }<br>         }<br>         <br>         path = name + ( path ? &#39;&gt;&#39; + path : &#39;&#39; );<br>         node = parent;<br>      }<br>      <br>      return path;<br>   }<br>} );<br><br><em>/**<br> * Used to attach to a element to always watch if its in the viewport.<br> *<br> * When scrolling, if element is in viewport add a parameter, a data attribute and a class name.<br> */<br></em>export class InViewportAnimation {<br>   _elements;<br>   <br>   constructor() {<br>      this.boundScrollEvent = false;<br>      this.elements = {};<br>      this.selectors = &#39;&#39;;<br>      <br>      const that = this;<br>      <br>      that.selectors = <strong><em>selectors</em></strong>;<br>      that.scroll();<br>      that.checkElements();<br>      that.toggleClasses();<br>   }<br>   <br>   addElement( element ) {<br>      if ( <strong><em>$</em></strong>( element ).length ) {<br>         if ( &#39;undefined&#39; !== typeof this.elements[ <strong><em>$</em></strong>( element ).getPath() ] ) {<br>            return;<br>         }<br>         <br>         <strong><em>$</em></strong>( element ).toggleClass( &#39;initiate-scroll-animation&#39;, true );<br>         this.elements[ <strong><em>$</em></strong>( element ).getPath() ] = element;<br>      }<br>   }<br>   <br>   setClasses( elem ) {<br>      const inViewport = this.inViewport( elem );<br>      elem.inViewport = inViewport;<br>      elem.attr( &#39;data-in-viewport&#39;, inViewport ).toggleClass( &#39;in-viewport&#39;, inViewport );<br>      <br>      this.setInlineClasses( inViewport, elem );<br>   }<br>   <br>   setInlineClasses( inViewport, elem ) {<br>      if ( ! inViewport ) {<br>         elem.css( { opacity: &#39;0.5&#39;, transform: &#39;translateY(15px)&#39;, transition: &#39;1s transform ease, 1s opacity ease&#39; } );<br>      } else {<br>         elem.css( { opacity: &#39;1&#39;, transform: &#39;translateY(0)&#39;, transition: &#39;1s transform ease, 1s opacity ease&#39; } );<br>      }<br>   }<br>   <br>   checkElements() {<br>      <strong><em>$</em></strong>( this.selectors ).each( ( i, elem ) =&gt; {<br>         this.addElement( elem );<br>      } );<br>   }<br>   <br>   scroll() {<br>      if ( ! this.boundScrollEvent ) {<br>         <strong><em>$</em></strong>( <strong><em>window </em></strong>).on( &#39;scroll&#39;, () =&gt; {<br>            this.checkElements();<br>            this.toggleClasses();<br>         } );<br>         this.boundScrollEvent = true;<br>      }<br>   }<br>   <br>   toggleClasses( elem = false ) {<br>      if ( ! elem ) {<br>         if ( ! <strong><em>Object</em></strong>.keys( this.elements ).length ) {<br>            return;<br>         }<br>         <br>         <strong><em>Object</em></strong>.keys( this.elements ).forEach( ( path ) =&gt; {<br>            if ( &#39;skip&#39; === this.elements[ path ] ) {<br>               return;<br>            }<br>            <br>            const elem = <strong><em>$</em></strong>( this.elements[ path ] );<br>            const inViewport = this.inViewport( elem );<br>            elem.inViewport = inViewport;<br>            elem.attr( &#39;data-in-viewport&#39;, inViewport ).toggleClass( &#39;in-viewport&#39;, inViewport );<br>            <br>            this.setInlineClasses( inViewport, elem );<br>            <br>            if ( inViewport ) {<br>               this.elements[ path ] = &#39;skip&#39;;<br>            }<br>         } );<br>      } else {<br>         const inViewport = this.inViewport( elem );<br>         elem.inViewport = inViewport;<br>         elem.attr( &#39;data-in-viewport&#39;, inViewport ).toggleClass( &#39;in-viewport&#39;, inViewport );<br>         <br>         this.setInlineClasses( inViewport, elem );<br>      }<br>   }<br>   <br>   inViewport( elem ) {<br>      return this.elementBottom( elem ) &gt; this.viewportTop() &amp;&amp; this.elementTop( elem ) &lt; this.viewportBottom();<br>   }<br>   <br>   elementBottom( elem ) {<br>      return this.elementTop( elem ) + <strong><em>$</em></strong>( elem ).outerHeight();<br>   }<br>   <br>   viewportTop() {<br>      return <strong><em>$</em></strong>( <strong><em>window </em></strong>).scrollTop();<br>   }<br>   <br>   elementTop( elem ) {<br>      return <strong><em>$</em></strong>( elem ).offset().top;<br>   }<br>   <br>   viewportBottom() {<br>      return this.viewportTop() + <strong><em>$</em></strong>( <strong><em>window </em></strong>).height();<br>   }<br>}</pre><h4>Debounce function</h4><p>Create a JS file called functions.js</p><pre><em>/**<br> * Calls the given function after the given interval.<br> *<br> * </em><strong><em>@param </em></strong><em>{Object} func Function name.<br> * </em><strong><em>@param </em></strong><em>{number} wait Time in milliseconds.<br> *<br> * </em><strong><em>@return </em></strong><em>{Function} Debounced function.<br> */<br></em>export const debounce = ( func, wait ) =&gt; {<br>   <br>   let timeout;<br>   <br>   <em>/**<br>    * Debounce function.<br>    */<br>   </em>return function() {<br>      <br>      const context = this,<br>         args = arguments;<br>      <br>      <em>/**<br>       * Later function.<br>       */<br>      </em>const later = function() {<br>         timeout = null;<br>         func.apply( context, args );<br>      };<br>      <br>      clearTimeout( timeout );<br>      <br>      timeout = setTimeout( later, wait );<br>   };<br>   <br>};</pre><h4>Scroll To Top Main JS file</h4><p>Create another file called scroll-to-top.js</p><pre><em>/**<br> * Back to Top.<br> *<br> * </em><strong><em>@package </em></strong><em>WPR<br> */<br><br></em>import { debounce } from &quot;./functions&quot;;<br>import { InViewportAnimation } from &#39;./in-viewport-animation&#39;;<br><br>( function ( $ ) {<br>   class BackToTop {<br>      <br>      <em>/**<br>       * Constructor.<br>       *<br>       * </em><strong><em>@return </em></strong><em>{void}<br>       */<br>      </em>constructor() {<br>         <br>         this.backToTopEl = $( &#39;#back-to-top&#39; );<br>         this.siteFooter = $( &#39;footer#colophon.site-footer&#39; );<br>         this.window = $( <strong><em>window </em></strong>);<br>         <br>         // The window scroll position after which we show the scroll to top button.<br>         this.scrollOffset = 200;<br>         <br>         if ( ! this.backToTopEl ) {<br>            return;<br>         }<br>         <br>         this.addEvents();<br>         <br>      }<br>      <br>      addEvents() {<br>         <br>         this.backToTopEl.on( &#39;click&#39;, this.scrollWindowToTop );<br>         this.window.on( &#39;scroll&#39;, () =&gt; debounce( this.toggleScrollToTopBtnVisibilty(), 1000 ) );<br>         <br>         new InViewportAnimation();<br>      }<br>      <br>      <em>/**<br>       * Toggle scroll button visibility.<br>       *<br>       * When the scroll position is large than scrollOffset<br>       * we will show the scroll to top button,<br>       * else hide it.<br>       *<br>       * </em><strong><em>@return </em></strong><em>{void}<br>       */<br>      </em>toggleScrollToTopBtnVisibilty() {<br>         <br>         // If the scroll position is larger than scrollOffset.<br>         if ( <strong><em>window</em></strong>.scrollY &gt; this.scrollOffset ) {<br>            this.backToTopEl.addClass( &#39;is-visible&#39; );<br>            <br>            const top_of_element = this.siteFooter.offset().top;<br>            const bottom_of_element = this.siteFooter.offset().top + this.siteFooter.outerHeight();<br>            const bottom_of_screen = $( <strong><em>window </em></strong>).scrollTop() + $( <strong><em>window </em></strong>).innerHeight();<br>            const top_of_screen = $( <strong><em>window </em></strong>).scrollTop();<br>            <br>            if ( ( bottom_of_screen &gt; top_of_element ) &amp;&amp; ( top_of_screen &lt; bottom_of_element ) ) {<br>               const diff = bottom_of_screen - top_of_element;<br>               this.backToTopEl.parent( &#39;.back-to-top&#39; ).css( &#39;bottom&#39;, ( 20 + diff ) + &#39;px&#39; );<br>            } else {<br>               this.backToTopEl.parent( &#39;.back-to-top&#39; ).css( &#39;bottom&#39;, &#39;20px&#39; );<br>            }<br>         } else {<br>            this.backToTopEl.removeClass( &#39;is-visible&#39; );<br>         }<br>      }<br>      <br>      <em>/**<br>       * Scroll window to top.<br>       *<br>       * When the back to top button is clicked scroll to top position.<br>       * </em><strong><em>@return </em></strong><em>{void}<br>       */<br>      </em>scrollWindowToTop() {<br>         <strong><em>window</em></strong>.scrollTo( {<br>            top: 0,<br>            behavior: &#39;smooth&#39;<br>         } );<br>      }<br>      <br>   }<br>   <br>   new BackToTop();<br>   <br>} )( jQuery );</pre><h4>Scroll To Top CSS</h4><pre>.back-to-top {<br>   display: none;<br><br>   @screen lg {<br>      position: fixed;<br>      bottom: 20px;<br>      right: 0;<br>      align-items: center;<br>      margin: auto;<br>      height: 140px;<br>      width: 100px;<br>      justify-content: center;<br>      z-index: 3;<br>      display: flex;<br>   }<br><br>   button {<br>      display: flex;<br>      flex-direction: column;<br>      align-items: center;<br>      color: #d5d7d8;<br>      cursor: pointer;<br>      font-style: normal;<br>      font-weight: 400;<br>      font-size: 12px;<br>      line-height: 137.74%;<br>      border-color: transparent;<br>      background-color: transparent;<br>      opacity: 0;<br>      -ms-user-select: none;<br>      user-select: none;<br>      -moz-user-select: none;<br>      -khtml-user-select: none;<br>      -webkit-user-select: none;<br>      -o-user-select: none;<br>      transition: all .5s ease;<br>      transition: color 0ms;<br><br>      &amp;.is-visible {<br>         opacity: 1;<br>         animation: fadein 1s;<br>         -moz-animation: fadein 1s;<br>         -webkit-animation: fadein 1s;<br>         -o-animation: fadein 1s;<br>      }<br><br>      svg {<br>         filter: brightness(0) saturate(100%) invert(100%) sepia(1%) saturate(1993%) hue-rotate(169deg) brightness(99%) contrast(70%);<br>      }<br><br>      &amp;:hover {<br>         color: grey;<br>         background-color: transparent;<br><br>         svg {<br>            filter: brightness(0) saturate(100%) invert(46%) sepia(9%) saturate(10%) hue-rotate(328deg) brightness(92%) contrast(85%);<br>         }<br>      }<br>   }<br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/182/1*qxXi8U3GEWV9a3iWLdiYuA.png" /></figure><p>That’s all folks</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5ce053a80fd0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Apply Different CSS Styles Based On Window Size (Responsively) Without Using JavaScript Window…]]></title>
            <link>https://imranhsayed.medium.com/apply-different-css-styles-based-on-window-size-responsively-without-using-javascript-window-78c27ab37558?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/78c27ab37558</guid>
            <category><![CDATA[css]]></category>
            <category><![CDATA[tailwind-css]]></category>
            <category><![CDATA[switching-css-classes]]></category>
            <category><![CDATA[windows]]></category>
            <category><![CDATA[screen-size]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Mon, 20 Dec 2021 07:05:52 GMT</pubDate>
            <atom:updated>2021-12-20T07:05:52.560Z</atom:updated>
            <content:encoded><![CDATA[<h3>Apply Different CSS Styles Based On Window Size (Responsively) Without Using JavaScript Window Event</h3><p>Switching CSS classes or properties based on screen size can be achieved using JavaScript as shown below. But handling such things with JavaScript window resize event is not as efficient to achieve it with CSS.</p><pre>$(window).on(&#39;resize&#39;, function() {<br>    if($(window).height() &gt; 400) {<br>        $(&#39;#body&#39;).addClass(&#39;your-class&#39;);<br>        $(&#39;#body&#39;).removeClass(&#39;your-class&#39;);<br>    }else{<br>        $(&#39;#body&#39;).addClass(&#39;your-class-2&#39;);<br>        $(&#39;#body&#39;).removeClass(&#39;your-class-2&#39;);<br>    }<br>})</pre><h4><strong>Using Tailwind</strong></h4><p>For example, if we want to create a feature where the child menu opens on mouseenter event and closes on mouseleave. But we only want to achieve this on desktop not on mobile. Let’s see how Tailwind helps us achieve it.</p><p>Let’s create two utility classes in Tailwind:</p><pre>@layer utilities {<br>   @responsive {<br><br>      .wp-sm-hidden {<br>         display: none;<br>         @screen lg {<br>            display: block;<br>         }<br>      }<br><br>      .wp-lg-hidden {<br>         display: block;<br>         @screen lg {<br>            display: none;<br>         }<br>      }<br>   }<br>}</pre><p>Now in our HTML code</p><pre>&lt;ul&gt;</pre><pre>&lt;li&gt;<br>   &lt;a class=&quot;parent-menu-item&quot; href=&quot;#&quot;&gt;Parent Menu item&lt;/a&gt;<br>   &lt;ul class=&quot;child-menu wp-sm-hidden lg:wp-lg-hidden&gt;<br>     Child menu<br>   &lt;/ul&gt;<br>&lt;/li&gt;<br>&lt;/ul&gt;</pre><p>The JavaScript</p><pre>const parentMenuItem = $(&#39;.parent-menu-item&#39;);<br>const childMenu = $(&#39;.child-menu&#39;);</pre><pre>parentMenuItem.on( &#39;mouseenter&#39;, ( event ) =&gt; openChildMenu( event ) );<br>parentMenuItem.on( &#39;mouseleave&#39;, ( event ) =&gt; closeChildMenu( event ) );</pre><pre>function openChildMenu( event ) {<br>   childMenu.removeClass( &#39;lg:wp-lg-hidden&#39; );<br>}</pre><pre>function closeChildMenu( event ) {<br>   childMenu.addClass( &#39;lg:wp-lg-hidden&#39; );<br>}</pre><h4>Explanation</h4><p>Now the class `lg:wpr-lg-hidden` will be applied on mouseenter on both desktop and mobile, but because there is a prefix lg: before the class name wp-lg:hidden the CSS properties will only be applied in the desktop and not on mobile and that solves our problem.</p><p>That’s all folks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=78c27ab37558" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Adding Local Fonts or Google Fonts In Tailwind CSS With WordPress]]></title>
            <link>https://imranhsayed.medium.com/adding-local-fonts-or-google-fonts-in-tailwind-css-with-wordpress-2850aac843fd?source=rss-bb850585be4f------2</link>
            <guid isPermaLink="false">https://medium.com/p/2850aac843fd</guid>
            <category><![CDATA[fonts]]></category>
            <category><![CDATA[local-fonts]]></category>
            <category><![CDATA[tailwind-css]]></category>
            <category><![CDATA[import]]></category>
            <category><![CDATA[google-fonts]]></category>
            <dc:creator><![CDATA[Imran Sayed]]></dc:creator>
            <pubDate>Fri, 10 Dec 2021 13:35:51 GMT</pubDate>
            <atom:updated>2021-12-10T13:35:51.526Z</atom:updated>
            <content:encoded><![CDATA[<p>In this blog, we will learn about how to add local fonts in TailwindCSS.<br>There are several reasons why you should include fonts locally. Watch <a href="https://www.youtube.com/watch?v=TUkaDzZbfl8&amp;list=PLD8nQCAhR3tT3ehpyOpoYeUj3KHDEVK9h&amp;index=59">this video</a> to know more.</p><h4>Step 1: Download the Fonts Locally</h4><p>Use <a href="https://google-webfonts-helper.herokuapp.com/fonts/lato?subsets=latin">Google Fonts helper</a></p><p><a href="https://google-webfonts-helper.herokuapp.com/fonts/lato?subsets=latin">google webfonts helper</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v2DG9ldVbAzdYY3pnuBm9w.png" /></figure><p>Place the fonts into the fonts directory.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/844/1*dkKGJisg9iSna5MCA41VJw.png" /></figure><h4>Step 2: Copy the fonts code into fonts.scss</h4><pre><em>/* lato-regular - latin */<br></em>@font-face {<br>   font-family: &#39;Lato&#39;;<br>   font-style: normal;<br>   font-weight: 400;<br>   src: url(&#39;lato-v20-latin-regular.eot&#39;); <em>/* IE9 Compat Modes */<br>   </em>src: local(&#39;&#39;),<br>   url(&#39;lato-v20-latin-regular.eot?#iefix&#39;) format(&#39;embedded-opentype&#39;), <em>/* IE6-IE8 */<br>   </em>url(&#39;lato-v20-latin-regular.woff2&#39;) format(&#39;woff2&#39;), <em>/* Super Modern Browsers */<br>   </em>url(&#39;lato-v20-latin-regular.woff&#39;) format(&#39;woff&#39;), <em>/* Modern Browsers */<br>   </em>url(&#39;lato-v20-latin-regular.ttf&#39;) format(&#39;truetype&#39;), <em>/* Safari, Android, iOS */<br>   </em>url(&#39;lato-v20-latin-regular.svg#Lato&#39;) format(&#39;svg&#39;); <em>/* Legacy iOS */<br></em>}<br><em>/* lato-700 - latin */<br></em>@font-face {<br>   font-family: &#39;Lato Bold&#39;;<br>   font-style: normal;<br>   font-weight: 700;<br>   src: url(&#39;lato-v20-latin-700.eot&#39;); <em>/* IE9 Compat Modes */<br>   </em>src: local(&#39;&#39;),<br>   url(&#39;lato-v20-latin-700.eot?#iefix&#39;) format(&#39;embedded-opentype&#39;), <em>/* IE6-IE8 */<br>   </em>url(&#39;lato-v20-latin-700.woff2&#39;) format(&#39;woff2&#39;), <em>/* Super Modern Browsers */<br>   </em>url(&#39;lato-v20-latin-700.woff&#39;) format(&#39;woff&#39;), <em>/* Modern Browsers */<br>   </em>url(&#39;lato-v20-latin-700.ttf&#39;) format(&#39;truetype&#39;), <em>/* Safari, Android, iOS */<br>   </em>url(&#39;lato-v20-latin-700.svg#Lato&#39;) format(&#39;svg&#39;); <em>/* Legacy iOS */<br></em>}</pre><h4>Step 3: Add the font configuration in tailwind.config.js</h4><pre>module.exports = {<br>   theme: {<br><br>      extend: {<br>         fontFamily: {<br>            &#39;lato&#39;: [ &quot;Lato&quot;, &#39;Helvetica&#39;, &#39;Verdana&#39;, &#39;Tahoma&#39;, &#39;sans-serif&#39; ],<br>            &#39;lato-bold&#39;: [ &quot;Lato Bold&quot;, &#39;Helvetica&#39;, &#39;Verdana&#39;, &#39;Tahoma&#39;, &#39;sans-serif&#39; ],<br>         },<br>}}};</pre><h4>Step 4: Enqueue the file in WordPress</h4><pre>namespace YouNameSpace;<br><br>function asset_loader() {<br>   // Register.<br><br>   wp_register_style( &#39;your-fonts&#39;, <em>THEME_DIST_URI </em>. &#39;fonts/fonts.css&#39;, [],  filemtime( <em>THEME_DIST_PATH </em>. &#39;fonts/fonts.css&#39; ) );<br><br>   // Enqueue global assets.<br>   wp_enqueue_style( &#39;your-fonts&#39; );<br><br>}<br><br>add_action( &#39;wp_enqueue_scripts&#39;, <em>__NAMESPACE__ </em>. &#39;\\asset_loader&#39; );</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/970/1*7DC4Qq4RcG4PLz7wF5nWTA.png" /></figure><p>That’s all folks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2850aac843fd" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>