How to create plugin configuration in Shopware?
18 November 2022

How to create plugin configuration in Shopware?

Plugin configuration enables the admin user to control the plugin's features and its configurations from Shopware backend. It's easy to create plugin configurations in Shopware and utilize the stored configuration in the store. Before that, you must know how to create a custom plugin in Shopware.

Create config.xml file inside your plugin directory //custom/plugins/WebbytroopsShopFinder/src/Resources/config/config.xml. We have created a configuration with an input filed

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/trunk/src/Core/System/SystemConfig/Schema/config.xsd">
    <card>
        <title>Minimal configuration</title>
        <title lang="de-DE">German Minimal configuration</title>
        <input-field type="text">
            <name>title</name>
            <label>Title</label>
            <placeholder>Title</placeholder>
            <required>1</required>
            <helpText>Title is the main primary section to enter</helpText>
        </input-field>
    </card>
</config>

Go to your store configuration page to update the value for the title field. You can find it under Extensions > My Extension > Shop Finder. You will have output similar to shared screenshot below:

If you have output with the above code, you have successfully created configuration for your plugin. It is simple process to create admin interface without any knowledge of backend architecture. Use the tags and put all your fields under the tags. There should be at least one and one to implement the configuration. Shopware does not come only with an input field text, there are several other input fields available. We will see those fields in brief along with the tags used in the config.xml file.

Configuration elements:

<Card>: Cards are simply a wrapper for your field that groups similar configurations in a single place. You can add a number of cards and add a number of fields there.
</strong>: The title tag is to show the label for the card. There is another with a lang attribute which is used to show the label in a different language. <br><strong><input-field></strong>: Input field tag used to create your custom field for the configurations. The important point is it should start with <strong><name></strong> element. After the <strong><name></strong> element you should put other elements such as <strong><label>, <placeholder>,<required>, <helptext>, <defaultValue></strong>, etc.</p> <p>Shopware has a rich set of input fields here is a list of those input fields:</p> <ul> <li>text</li> <li>textarea</li> <li>text-editor</li> <li>url</li> <li>password</li> <li>int</li> <li>float</li> <li>bool</li> <li>checkbox</li> <li>datetime</li> <li>date</li> <li>time</li> <li>colorpicker</li> <li>single-select</li> <li>multi-select</li> </ul> <h3>Advanced custom input field</h3> <p>Shopware does not only limit to general fields for store configuration, you can declare complex configuration with <strong><component anme="componentName"></strong> element. You can render the existing admin components as well as your own component. Here are some supported <a href="https://developer.shopware.com/docs/guides/plugins/plugins/plugin-fundamentals/add-plugin-configuration#advanced-custom-input-fields">advanced components</a> by Showpare:</p> <ul> <li>sw-entity-single-select</li> <li>sw-entity-multi-id-select</li> <li>sw-media-field</li> <li>sw-text-editor</li> <li>sw-snippet-field</li> </ul> <h3>Example of store configuration file</h3> <p>File name: <strong><project-directory>//custom/plugins/WebbytroopsShopFinder/src/Resources/config/config.xml</strong></p> <pre><code><?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/trunk/src/Core/System/SystemConfig/Schema/config.xsd"> <card> <title>Minimal configuration</title> <title lang="de-DE">German Minimal configuration</title> <input-field type="bool"> <name>isenable</name> <label>Is Enable</label> <required>1</required> <defaultValue>true</defaultValue> </input-field> <input-field type="text"> <name>title</name> <label>Title</label> <defaultValue>Hey Default value</defaultValue> <placeholder>Title</placeholder> <required>1</required> <helpText>Title is the main primary section to enter</helpText> </input-field> <input-field type="single-select"> <name>mailMethod</name> <options> <option> <id>smtp</id> <name>English smtp</name> <name lang="de-DE">German smtp</name> </option> <option> <id>pop3</id> <name>English pop3</name> <name lang="de-DE">German pop3</name> </option> </options> <defaultValue>smtp</defaultValue> <label>Mail method</label> <label lang="de-DE">Versand-Protokoll</label> </input-field> </card> <card> <title>Advanced Configuration</title> <title lang="de-DE">Erweiterte Einstellungen</title> <input-field type="password"> <name>apikey</name> <label>Secret Apikey</label> <label lang="de-DE">Geheimer Apikey</label> <helpText>Your secret token for xyz...</helpText> <helpText lang="de-DE">Dein geheimer Token für xyz...</helpText> </input-field> <component name="sw-entity-single-select"> <name>exampleProduct</name> <entity>product</entity> <label>Choose a product for the plugin configuration</label> </component> <component name="sw-entity-multi-id-select"> <name>exampleMultiProductIds</name> <entity>product</entity> <label>Choose multiple products IDs for the plugin configuration</label> </component> <component name="sw-media-field"> <name>pluginMedia</name> <label>Either upload media or choose existing one from the media manager</label> </component> <component name="sw-text-editor"> <name>textEditor</name> <label>Write some nice text with WYSIWYG editor</label> </component> <component name="sw-snippet-field"> <name>snippetField</name> <label>Description</label> <snippet>myPlugin.test.snippet</snippet> </component> </card> </config></code></pre> <h3>Other topics you may like:</h3> <ul> <li><a href="https://webbytroops.com/how-to-get-plugin-configuration-in-shopware/">How to get plugin configuration value in Shopware</a></li> <li><a href="https://webbytroops.com/how-to-create-a-custom-plugin-in-shopware/">How to create custom controller in Shopware</a></li> </ul> </div> <div class="lg:col-span-3 md:col-span-5 lg:sticky self-start md:hidden block mt-10 "> <!-- Tags --> <div class="lg:mt-12 mt-8 md:mt-10 border-b "> <p class="text-base md:text-lg xl:text-2xl pb-8">Tags</p> <div class="flex flex-wrap gap-2 mb-8"> <a href="https://webbytroops.com/blog/tag/e-commerce" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> E-Commerce </a> <a href="https://webbytroops.com/blog/tag/ecommerce" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> eCommerce </a> <a href="https://webbytroops.com/blog/tag/shopware" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> shopware </a> <a href="https://webbytroops.com/blog/tag/shopware-6" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> Shopware 6 </a> <a href="https://webbytroops.com/blog/tag/shopware-plugin" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> Shopware-plugin </a> </div> </div> <!-- Categories --> <p class=" text-base md:text-lg xl:text-2xl py-8">Categories</p> <div class="flex flex-wrap gap-2"> <a href="https://webbytroops.com/blog/category/ecommerce" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> eCommerce </a> <a href="https://webbytroops.com/blog/category/shopware" class="btn btn-primary lg:px-6 lg:py-3 sm:text-sm text-sm px-4 py-2 rounded-full font-medium"> Shopware </a> </div> <!-- Download Free Ebook --> <div class="bg-primary-bggray lg:mt-14 mt-10 rounded-3xl" x-data="initEbookForm()" x-cloak> <p class=" lg:text-2xl md:text-xl sm:text-lg sm:text-center md:text-start text-base px-6 font-medium lg:pt-14 md:pt-10 pt-7"> Download The Free E-book & Launch Your Brand Strategically </p> <div class="sm:mt-4"> <img class=" lg:w-full md:h-auto sm:h-[350px] w-dvw h-[290px] object-fill" src="https://webbytroops.com/static/frontend/Webbytroops/Hyva/en_US/images/Blogimage.png" alt=""> </div> <button type="submit" class=" font-medium lg:text-base sm:text-sm text-xs py-2 lg:py-4 sm:py-3 px-4 sm:px-6 lg:px-8 rounded-full bg-white hover:bg-primary-lighter hover:text-white lg:mb-12 mb-6 mx-4 lg:mx-8" @click="openModal()"> Download Free </button> <!-- Modal --> <div x-show="open" x-transition class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50"> <div class="bg-primary-ebgrey p-10 font-sans font-medium"> <div class="2xl:container 2xl:px-0 "> <div class="flex-wrap overflow-hidden relative "> <div @click.outside="closeModal()"> <h2 class="text-3xl responsive-heading mb-11 lg:w-[606px] lg:leading-[120%] md:leading-[130%]">Download The Free E-book & Launch Your Brand Strategically</h2> <form x-init="initValidation($el)" @submit.prevent="submitFormBook" method="post" autocomplete="off" action="https://webbytroops.com/ebook/index/submit/" class="flex flex-col gap-y-8 lg:w-[541px]"> <input name="form_key" type="hidden" value="Y5Fwi0DCk16FCwVW" /> <div class="field field-reserved"> <input type="text" class="form-input bg-transparent w-full" name="name" placeholder="Full Name*" required> </div> <div class="field field-reserved"> <input type="email" class="form-input bg-transparent w-full" name="email" placeholder="Email*" required> </div> <div class="flex justify-end gap-2"> <button type="button" @click="closeModal()" class="bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded"> Cancel </button> <button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white px-6 py-2 rounded"> Submit </button> </div> <!-- Success / Error message --> <p x-show="successMessage" x-text="successMessage" class="text-green-600 font-medium mt-2"> </p> </form> </div> </div> </div> </div> </div> </div> </div> <!-- Blog FAQs --> <div class="mpcss"> <div class="flex items-center mt-8"> <div class=""> <p class="m-0 font-semibold lg:text-2xl md:text-xl text-lg pb-1">Share this post</p> </div> <div class="ml-8"> <div class="post-sharing-button flex gap-2"> <a aria-label="facebook" target="_blank" rel="nofollow noopener" href="https://twitter.com/share?text=&url=https://webbytroops.com/blog/how-to-create-plugin-configuration-in-shopware"> <img class="img-responsive w-[30px] h-[30px]" src="https://webbytroops.com/static/frontend/Webbytroops/Hyva/en_US/images/twitter.png" alt="Share on Twitter" /> </a> <a aria-label="facebook" target="_blank" rel="nofollow noopener" href="https://www.facebook.com/sharer/sharer.php?u=https://webbytroops.com/blog/how-to-create-plugin-configuration-in-shopware"> <img class="img-responsive w-[30px] h-[30px] cursor-pointer" src="https://webbytroops.com/static/frontend/Webbytroops/Hyva/en_US/images/facebook.png" alt="Share on Facebook" /> </a> <a aria-label="linkedin" target="_blank" rel="nofollow noopener" href="https://www.linkedin.com/shareArticle?mini=true&url=https://webbytroops.com/blog/how-to-create-plugin-configuration-in-shopware&title=&summary=&source="> <img class="img-responsive w-[30px] h-[30px] cursor-pointer" src="https://webbytroops.com/static/frontend/Webbytroops/Hyva/en_US/images/linkedin.png" alt="Share on Linkedin" /> </a> </div> </div> </div> </div> </div> </div> </div> <div class="mp-clear"></div> <div class="block-blog-related about-admin hidden"> <h2>About the Author</h2> <div class="related-content-container"> <div class="author-content-image"> <img class="img-responsive" src="https://webbytroops.com/static/frontend/Webbytroops/Hyva/en_US/Mageplaza_Blog/media/images/no-artist-image.jpg"> </div> <div class="author-content-information"> <div class="author-name">Admin</div> <p class="author-description"> </p> </div> <div class="mp-clear"></div> </div> </div> <!-- --> </div> <style> .default-cmt__content__cmt-content.row { padding-inline-start: 40px; } </style> <script> document.addEventListener('DOMContentLoaded', function() { if (document.getElementById('card-carousel')) { new Splide('#card-carousel', { perPage: 3, breakpoints: { 640: { perPage: 1 }, 768: { perPage: 2 }, 1024: { perPage: 2 }, } }).mount(); } }); var cmtBox = document.querySelector('.default-cmt__content__cmt-block__cmt-box__cmt-input'); var submitCmt = document.querySelector('.default-cmt__content__cmt-block__cmt-box__cmt-btn__btn-submit'); var defaultCmt = document.querySelector('ul.default-cmt__content__cmt-content:first-child'); var likeBtn = defaultCmt.querySelectorAll('.btn-like'); var replyBtn = defaultCmt.querySelectorAll('.btn-reply'); let loginBtnCmt = document.querySelector('.default-cmt__cmt-login__btn-login'); if (loginBtnCmt) { loginBtnCmt.addEventListener('click', function() { var socialPopup = document.querySelector(".social-login-popup"); if (socialPopup) { openMyDialog(); showLogin(); } else { window.location.href = loginUrl; } }); } function initCustomerCommentForm() { return { errors: 0, hasCaptchaToken: 0, showPassword: false, displayErrorMessage: false, errorMessages: [], setErrorMessages(messages) { this.errorMessages = [messages]; this.displayErrorMessage = this.errorMessages.length }, submitForm() { this.validate() .then(() => { const $form = document.querySelector('#default-cmt__content__cmt-block__guest-form'); if (this.errors === 0) { this.dispatchCommentRequest($form); } }) .catch((invalid) => { if (invalid.length > 0) { invalid[0].focus(); } }); }, dispatchCommentRequest: function(form) { callApiSubmitComment(); } } } function submitComment() { if (isLogged === 'Yes') { submitCmt.addEventListener('click', function() { callApiSubmitComment(); }); } } submitComment(); async function callApiSubmitComment() { var messagesContainer = document.querySelector('.default-cmt__content__cmt-block__cmt-box .messages'); if (messagesContainer) { messagesContainer.style.display = 'none'; } var cmtBox = document.querySelector('.default-cmt__content__cmt-block__cmt-box__cmt-input'); var submitCmt = document.querySelector('.default-cmt__content__cmt-block__cmt-box__cmt-btn__btn-submit'); var cmtText = cmtBox.value; if (cmtText.trim().length) { document.querySelector('.default-cmt_loading').style.display = 'block'; this.disabled = true; await ajaxCommentActions(cmtText, submitCmt); cmtBox.value = ''; document.querySelector('.default-cmt_loading').style.display = 'none'; submitCmt.disabled = false; } else { var cmtInputParent = document.querySelector('.default-cmt__content__cmt-block__cmt-box__cmt-input') .parentElement; cmtInputParent.insertAdjacentHTML('beforeend', messengerBox.cmt_warning); } } // ajax call api to comments function ajaxCommentActions(cmtText, inputEl, checkReply, cmtId, parentComment) { var isReply = (typeof checkReply !== 'undefined') ? 1 : 0, replyId = (typeof cmtId !== 'undefined') ? cmtId : 0, displayReply = (typeof checkReply !== 'undefined'); var guestName = document.querySelector('#default-cmt__content__cmt-block__guest-box__name-input')?.value; var guestEmail = document.querySelector('#default-cmt__content__cmt-block__guest-box__email-input')?.value; let url = window.location.href; const body = new URLSearchParams({ form_key: hyva.getFormKey(), cmt_text: cmtText, isReply: isReply, replyId: replyId, guestName: guestName, guestEmail: guestEmail }); fetch(url, { headers: { contentType: "application/x-www-form-urlencoded; charset=UTF-8", "X-Requested-With": "XMLHttpRequest" }, body: body, method: "POST", mode: "cors", credentials: "include" }) .then(response => response.json()) .then(data => { switch (data.status) { case 'duplicated': document.querySelector('.default-cmt__content__cmt-block__cmt-box__cmt-input').parentElement .appendChild(document.createRange().createContextualFragment(messengerBox .exist_email_warning)); break; case 3: document.querySelector('.default-cmt__content__cmt-block').insertAdjacentHTML('afterbegin', messengerBox.comment_approve); break; case 1: displayComment(data, displayReply); var cmtCount = document.querySelectorAll('.default-cmt li').length; if (document.querySelector('.mp-cmt-count')) { document.querySelector('.mp-cmt-count').textContent = cmtCount; } inputEl.value = ''; break; case 'error': if (checkReply !== 'undefined') { parentComment.insertAdjacentHTML('beforeend', data.error); } else { document.querySelector('.default-cmt').insertAdjacentHTML('beforeend', data.error); } break; } }) .catch(error => console.error('Error:', error)); } // handle display comments function displayComment(cmt, isReply) { function htmlComment(text) { var html = ''; var sub = text.split("\n"); for (var i = 0; i < sub.length; i++) { html += '<p>' + sub[i] + '</p>'; } return html; } var cmtRow = document.createElement('li'); cmtRow.style.width = '100%'; cmtRow.id = 'cmt-id-' + cmt.cmt_id; cmtRow.className = 'default-cmt__content__cmt-content__cmt-row cmt-row-' + cmt.cmt_id + ' cmt-row col-m-12' + (isReply ? ' reply-row' : ''); cmtRow.setAttribute('data-cmt-id', cmt.cmt_id); if (isReply) { cmtRow.setAttribute('data-reply-id', cmt.reply_cmt); } cmtRow.innerHTML = '<div class="cmt-row__cmt-username"> ' + '<span class="cmt-row__cmt-username username username__' + cmt.cmt_id + '">' + cmt.user_cmt + '</span> ' + '</div>' + '<div class="cmt-row__cmt-content"> ' + '<p>' + htmlComment(cmt.cmt_text) + '</p> ' + '</div>' + '<div class="cmt-row__cmt-interactions interactions"> <div class="interactions__btn-actions"> ' + '<a class="interactions__btn-actions action btn-like mpblog-like" data-cmt-id="' + cmt.cmt_id + '" click="1">' + '<i class="fa fa-thumbs-up" aria-hidden="true" style="margin-right: 3px"></i>' + '<span class="count-like__like-text"></span>' + '</a>' + '<a class="interactions__btn-actions action btn-reply" data-cmt-id="' + cmt.cmt_id + '">' + reply + '</a> ' + '</div>' + '<div class="interactions__cmt-createdat"> ' + '<span>' + cmt.created_at + '</span> ' + '</div> '; if (isReply) { var replyCmtId = cmt.reply_cmt; var replyCmtList = document.querySelectorAll('.default-cmt__content__cmt-content__cmt-row'); replyCmtList.forEach(function(cmtEl) { if (cmtEl.getAttribute('data-cmt-id') === replyCmtId) { var replyList = cmtEl.querySelector('ul.default-cmt__content__cmt-content:first-child'); if (!replyList) { var newUl = document.createElement('ul'); newUl.className = 'default-cmt__content__cmt-content row'; newUl.appendChild(cmtRow); cmtEl.appendChild(newUl); likeComment(cmtRow.querySelectorAll('.btn-like')); showReply(cmtRow.querySelectorAll('.btn-reply')); } else { replyList.appendChild(cmtRow); likeComment(cmtRow.querySelectorAll('.btn-like')); showReply(cmtRow.querySelectorAll('.btn-reply')); } return; } }); } else { defaultCmt.appendChild(cmtRow); likeComment(cmtRow.querySelectorAll('.btn-like')); showReply(cmtRow.querySelectorAll('.btn-reply')); } } // handle click like comment function likeComment(btns) { btns.forEach(function(likeEl) { likeEl.addEventListener('click', function() { var cmtId = this.getAttribute('data-cmt-id'); var cmtRowContainer = this.closest('.default-cmt__content__cmt-content__cmt-row'); if (isLogged === 'Yes') { var likeCountText = this.querySelector('span').textContent.trim(); var likeCount = parseInt(likeCountText, 10) || 0; // Convert to integer, default to 0 if NaN if (this.getAttribute('click') === '1') { if (this.classList.contains('mpblog-liked')) { this.style.color = '#333333'; likeCount--; this.querySelector('span').textContent = (likeCount === 0) ? "" : likeCount; this.classList.remove('mpblog-liked'); } else { likeCount++; this.querySelector('span').textContent = likeCount; this.style.color = likedColor; this.classList.add('mpblog-liked'); } fetch(window.location.href, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', "X-Requested-With": "XMLHttpRequest" }, body: 'cmtId=' + cmtId, mode: "cors", credentials: "include" }) .then(response => response.json()) .then(response => { if (response.status === 'ok') { likeEl.setAttribute('click', '1'); } else if (response.status === 'error' && response.hasOwnProperty( 'error')) { var errorElement = document.createElement('div'); errorElement.innerHTML = response.error; defaultCmt.appendChild(errorElement); } }) .catch(error => console.error('Error:', error)); } likeEl.setAttribute('click', '0'); } else { cmtRowContainer.insertAdjacentHTML('beforeend', messengerBox.login_warning); setTimeout(function() { var errorNotification = document.querySelector( '.message.error.message-error'); if (errorNotification) { errorNotification.parentElement.removeChild(errorNotification); } }, 3000); } }); }); } likeComment(likeBtn); // handle show reply comment function showReply(btns) { btns.forEach(function(btn) { btn.addEventListener('click', function() { var cmtId = (typeof closestWithDataAttr(btn, 'data-cmt-id') !== 'undefined') ? closestWithDataAttr(btn, 'data-cmt-id') : btn.getAttribute('data-cmt-id'); var inputCmtID = this.getAttribute('data-cmt-id'); var cmtRowCmt = document.querySelector('#cmt-row'); var cmtRowContainer = this.closest('.default-cmt__content__cmt-content__cmt-row'); if (document.querySelectorAll('.cmt-row__reply-row.row__' + inputCmtID).length) { cmtRowContainer = document.querySelector("#cmt-id-" + cmtId + " ul:last-child"); } var cmtRow = cmtRowContainer.querySelector('.cmt-row__reply-row.row__' + inputCmtID); var cmtName = document.querySelector(".username__" + inputCmtID).textContent; if (isLogged === 'Yes') { if (cmtRowCmt) { cmtRowCmt.style.display = (cmtRowCmt.style.display === 'none') ? 'block' : 'none'; cmtRowCmt.parentElement.removeChild(cmtRowCmt); } if (cmtRow) { cmtRow.style.display = (cmtRow.style.display === 'none') ? 'block' : 'none'; cmtRow.parentElement.removeChild(cmtRow); } else { cmtRowContainer.insertAdjacentHTML('beforeend', '<div id="cmt-row" class="cmt-row__reply-row row row__' + inputCmtID + ' col-md-12">' + '<div class="reply-form__form-input form-group col-xs-8 col-md-6">' + '<label for="reply_cmt' + inputCmtID + '"></label>' + '<input type="text" id="reply_cmt' + inputCmtID + '" class="form-group__input form-control" placeholder="Press enter to submit reply" value="' + cmtName + ' " autofocus onfocus="this.setSelectionRange(1000,1001);"/>' + '</div>' + '</div>'); var input = document.getElementById('reply_cmt' + inputCmtID); input.closest('.form-group').appendChild( document.querySelector( '.default-cmt__content__cmt-block__cmt-box__cmt-btn .default-cmt_loading' ).cloneNode(true) ); input.focus(); submitReply(input, cmtId, cmtRowContainer); } } else { cmtRowContainer.insertAdjacentHTML('beforeend', messengerBox.login_warning); setTimeout(function() { var errorNotification = document.querySelector( '.message.error.message-error'); if (errorNotification) { errorNotification.parentElement.removeChild(errorNotification); } }, 3000); } }); }); } // handle find comment id closest function closestWithDataAttr(element, attribute) { while (element && !element.getAttribute(attribute)) { element = element.parentNode; } return element ? element.getAttribute(attribute) : null; } showReply(replyBtn); var firstCmtRow = document.querySelector('li.default-cmt__content__cmt-content__cmt-row:first-child'); if (firstCmtRow) { firstCmtRow.style.borderTop = 'none'; } // handle reply comment function submitReply(input, replyId, parentComment) { input.addEventListener('keypress', async function(e) { var text = input.value; if (text !== '') { if (e.keyCode === 13) { input.nextElementSibling.style.display = 'block'; input.disabled = true; await ajaxCommentActions(text, input, true, replyId, parentComment); input.closest('.cmt-row__reply-row').style.display = 'none'; input.nextElementSibling.style.display = 'none'; input.disabled = false; var cmtRow = document.getElementById('cmt-row'); if (cmtRow) { cmtRow.remove(); } } } }); } function initEbookForm() { return { open: false, loading: false, successMessage: '', openModal() { this.open = true; }, closeModal() { this.open = false; }, validator: null, initValidation(el) { this.validator = hyva.formValidation(el); }, submitFormBook(event) { // event.preventDefault(); this.validator.validate() .then(() => { const form = event.target; const formData = new FormData(form); fetch(form.action, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { console.log(response); if (response.ok) { form.reset(); this.successMessage = 'E-book sent to your email!'; // Auto-close popup after 2s setTimeout(() => this.closeModal(), 2000); } else { this.successMessage = 'Something went wrong.'; setTimeout(() => this.successMessage = '', 2000); } }) .catch(error => { this.loading = false; this.successMessage = 'Error. Please try again.'; setTimeout(() => this.successMessage = '', 2000); }); }) .catch((invalid) => { if (invalid.length > 0) { invalid[0].focus(); } }); } }; } </script> <script> document.addEventListener('DOMContentLoaded', function() { const blogContent = document.getElementById('blog_content'); const tableOfContent = document.getElementById('table_of_content'); const tocList = document.createElement('ul'); const headings = blogContent.querySelectorAll('h2, h3'); let section = null; let h2Index = 0; let h3Index = 0; headings.forEach((heading, index) => { let headingSlug = heading.textContent.trim().toLowerCase() .replace(/[^a-z0-9]+/g, '-') // replace non-alphanumerics with hyphen .replace(/^-+|-+$/g, ''); // trim hyphens let headingId = heading.tagName === 'H2' ? `section-${headingSlug}` : `sub-section-${headingSlug}`; const li = document.createElement('li'); const link = Object.assign(document.createElement('a'), { href: `#${headingId}`, textContent: heading.textContent }); li.appendChild(link) heading.id = headingId; if (heading.tagName === 'H2') { tocList.appendChild(li); section = li; } else if (heading.tagName === 'H3' && section) { let subsection = section.querySelector('ul'); if (!subsection) { subsection = document.createElement('ul'); section.appendChild(subsection); } subsection.appendChild(li); } }); tableOfContent.appendChild(tocList); }); </script> <script> document.addEventListener('DOMContentLoaded', function () { document.querySelectorAll('pre code').forEach(code => { code.classList.add('font-mono', 'rounded-md', 'text-sm', 'leading-relaxed'); hljs.highlightElement(code); }); }); </script></div></div></main><footer class="page-footer"><div class="footer content"><script> addEventListener('DOMContentLoaded', () => { for (const [selector, label] of Object.entries([])) { const target = document.querySelector(selector); target && target.setAttribute('aria-label', label); } }, {once: true}) </script> <section class=" bg-black"> <div class="2xl:container"> <div class="pt-16 pb-8 lg:mx-8"> <div class="grid grid-cols-1 lg:grid-cols-4 lg:gap-6 text-white lg:px-3 md:px-7 px-5"> <ul class="font-sans text-base"> <li class="md:pb-4 flex"> <img class="" src="https://webbytroops.com/static/frontend/Webbytroops/Hyva/en_US/images/logo-white.png" alt="WebbyTroops Store"> </li> <li class="flex items-start gap-5 md:py-[6px] py-3"> <span><svg xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 384 512" class="text-white" width="20" height="20" role="img"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2023 Fonticons, Inc. --><path d="M215.7 499.2C267 435 384 279.4 384 192C384 86 298 0 192 0S0 86 0 192c0 87.4 117 243 168.3 307.2c12.3 15.3 35.1 15.3 47.4 0zM192 128a64 64 0 1 1 0 128 64 64 0 1 1 0-128z"/><title>location-dot

Sukh Sagar Apartment, Behind Kothari Hospital, Bikaner - 334001, Rajasthan, India

  • phone-volume +91-7014424540
  • envelope [email protected]
  • facebook instagram x-twitter linkedin-in
  • visa mastercard paypal apple-pay google-pay
    Copyright 2026 © WebbyTroops Technologies. All Rights Reserved.