Shopify Section load event in Liquid file (Shopify) - shopify

I am Shopify developer. I designed a slideshow using Flickity library in Shopify. My slider working fine on URL when load but it's not work on Shopify Theme Editor, till I am not saved the design. after save design is working fine.
I am using this script in section file it's not working but when I paste this code in theme.liquid file it's working fine on both sides.
I don't want like this image
<script>
{% if request.design_mode %}
console.log("123");
document.addEventListener("shopify:section:load", function() {
console.log("abc");
var elem = document.querySelector('.carousel');
var flkty = new Flickity( elem, {
autoPlay: "{{ section.settings.autoplay_slide }}",
pageDots: true,
contain: true,
wrapAround: false,
imagesLoaded: true,
accessibility: false
});
});
{% endif %}
</script>
I want, that when i select section from theme editor it's working smoothly.
I want like this image

Instead of using shopify:section:load which fires only inside the theme editor (that's why you can't get it working outside of theme editor), you should include this <script> tag in the end of your section's code and change it a bit:
<script>
{% if request.design_mode %}
console.log("123");
let flkty; // for later use
document.addEventListener("DOMContentLoaded", function() { // run this script after window is ready and scripts are loaded
console.log("abc");
var elem = document.querySelector('.carousel');
if (elem) { // check if element was found before using it
flkty = new Flickity( elem, {
autoPlay: "{{ section.settings.autoplay_slide }}",
pageDots: true,
contain: true,
wrapAround: false,
imagesLoaded: true,
accessibility: false
});
}
});
{% endif %}
</script>

Related

Workbox cache not used by <img /> tag

Setup
"workbox-cdn": "^5.1.4",
"nuxt": "^2.15.2"
Context
My app, Pictalk, let users save and get pictograms. So basically every user has a custom set of pictograms. For now, it works only online but I want to implement offline-mode.
Technical Details
I display all my pictograms with the html <img .../> tag.
Every time I load a new pictogram I do so:
created(){
if(navigator.onLine){
caches.open('pictos').then((cache) => {
cache.add(this.collection.path)
.then(() => {})
.catch((err)=> {console.log(err)})
});
}
},
Here is a screenshot of the Cache Storage :
As we see the URL is correct and the requests are cached correctly.
Problem
The <img .../> tag doesn't use the workbox cache I created.
Found out the solution here and here.
Here is the files I had to modify in order to make it work :
First, my <img/> tags had to use the crossorigin="anonymous" method :
<img class="image" style :src="path" crossorigin="anonymous"/>
Once the <img/> tags are more flexible with their origin we can start building our custom registered workbox route:
// plugins/workboxConfig.js
workbox.routing.registerRoute(
new RegExp('https://myapi\\.somewhere\\.com/pictalk/image/.*\\.(png|jpg|jpeg)'),
new workbox.strategies.CacheFirst({
cacheName: 'pictos',
plugins: [
new workbox.cacheableResponse.CacheableResponsePlugin({ statuses: [200] }),
new workbox.rangeRequests.RangeRequestsPlugin(),
],
matchOptions: {
ignoreSearch: true,
ignoreVary: true
}
}),
);
I had to declare this file here in the nuxtjs.config.js :
pwa: {
workbox: {
cachingExtensions: '#/plugins/workboxConfig.js'
}
}

IOS loading failure on large (more than 50) images using swiper

trying to build a website with swiper with bigger number of photos.
On various browsers on Mac and PC it works well, but fail on ios safari after more than 50 images are within my images array.
Failure is that IOS Safari try to load the page, refreshes automatically and try again and again, then show a message saying that website loading failed.
Same on IOS Firefox works.
The source I build up using some PHP within a CMS (LEPTON), after collection the image names (without size & extension) within an array:
foreach( $aImages as $image )
{
$div .= ' <div class="swiper-slide" data-title="' . $image . '" >' . PHP_EOL;
$div .= ' <img data-src="' . $imageURL . $image . '_8b.png" data-srcset="' . $imageURL . $image . '_24b.png 1200w" class="swiper-lazy">' . PHP_EOL;
$div .= ' <div class="swiper-lazy-preloader"></div>' . PHP_EOL;
$div .= ' </div>' . PHP_EOL;
}
my JS to initialize the slider looks like:
$(document).ready(function () {
//initialize swiper when document ready
var mySwiper = new Swiper ('.swiper-container', {
/* parameters with different value than default */
// Duration of transition between slides (in ms)
speed: 1400,
// fading effect
effect: 'fade',
fadeEffect: {
crossFade: true
},
// show hand on image
grabCursor: true,
// add visibility class to currently showing image
watchSlidesProgress: true,
watchSlidesVisibility: true,
// Lazy Loading
preloadImages: false,
lazy: {
loadPrevNext: true,
loadPrevNextAmount: 1,
loadOnTransitionStart: true,
},
// continuous loop mode
loop: true,
// double click zoom into image
zoom: false,
// enable keyboard navigation prev/next
keyboard: {
enabled: true,
onlyInViewport: true,
pageUpDown: true,
},
// Navigation arrows
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
hideOnClick: false,
},
// center image
centeredSlides: true,
centeredSlidesBounds: false,
// autoplay
autoplay: {
delay: 3000,
disableOnInteraction: true
},
autoplay: false,
});
Any idea what's wrong or what I can change in order to solve my issue ?
Thx in advance
I think the solution for my problem are the virtual slides ....
Testing this but getting other issues there ....
And the available examples in native JS does not really help.
Update: Finally I got it running with virtual slides.
However there is a bug within combination with fadings.
Without fade parameter it is running.

How to setup the baseurl for nunjucks

I want to deploy the site to different servers for testing, production etc. So defining a basepath by changing one variable or setting would be the prefered method. What is the best method to implement this?
Currently I have set a variable in layout file as follows.
{% set siteBaseurl = '/demo' %}
It is used everywhere else I define paths as follows
<img src="{{ siteBaseurl }}/images/logo.png" />
I found the perfect solution. As mentioned in the gulp-nunjucks-render package you can parse variables to the template via gulp task. Using dotenv you can get it from a single configuration file. Here's how I set it up
.env
NODE_ENV=development
BASEURL=\demo
gulpfile.js
const nunjucksData = {
baseurl: process.env.BASEURL
};
gulp.task('nunjucks', function () {
nunjucksRender.nunjucks.configure(['app/templates/']);
// Gets .html and .nunjucks files in pages
return gulp.src('app/pages/**/*.+(html|njk|nunj|nunjucks)')
// Renders template with nunjucks
.pipe(nunjucksRender({
data: nunjucksData,
path: ['app/templates/'] // String or Array
}))
.pipe(gulpif(isProd, htmlmin()))
// output files in app folder
.pipe(gulp.dest('dist'));
});
layout.njk
<img src="{{ baseurl }}/images/logo.png" />
Hope this helps

How to render a template with VueJS and Axios?

I have a Vue app that generates as many forms as the user likes. Each form represent a 'risk' in this 'risks' data model:
var app = new Vue({
el: '#app',
data: {
risks: [
{
'risk_name': '', 'fields': [{'field': '', 'type': ''}], 'errors':[]
}
],
},
Then I send the 'risks' to a post API request. Then I make a second get request that brings back a template with the processed data as JSON. So far so good. However, how do I render the template (new page) with this data.
This is how I receive the data:
Submit() {
if (this.checkValidity()) {
console.info(this.risks)
axios.post('risks', this.risks)
.then(function(response) {
axios.get('risks')//This gets the data back
})
.catch(function(error) {
alert('This Error occured: ' + error)
})
}
},
This is the GET API call that I called above (Flask):
#app.route('/risks', methods=['GET'])
def getInsurancePolicyForm():
risks = getTables(app.metadata)
return render_template('form.html', risks=risks)
I can see the rendered template in developer tools, but the page the user sees remains the same.
Your page should be focussed on the risks object instead of the response from the API call.
When the user selects options, add them to the risks data object so your risks object looks like:
risks: [
{
'risk_name': '', 'fields': [{'field': 'My Field', 'type': 'text', modelToHoldData: ''}], 'errors':[]
}
]
Then, when the user clicks on Submit, by all means send it to the API but you don't need a template from there, use the risks object like so (remembering to hide the form they've just chosen their fields with):
<div v-for="risk in risks">
<label>{{risk.field}}</label>
<input type="text" v-if="risk.type === 'text'" v-model="risk.modelToHoldData" />
</div>
You can adjust the above example to add as many variations of the example as you allow the user to select.
Once all this is done and you need access to the data the user enters, you can loop through the array again and just access the modelToHoldData prop on each of the risks.

OctoberCMS Get Theme Settings data in Api/Web service

I have created an OctoberCMS theme which works very well. And i have my current and activated theme.yaml like this.
theme.yaml
name: 5P Group
description: '5P Group OctoberCMS theme. A client website that contains preconfigured pages for static pages, a blog and client area..'
author: Technobrave
homepage: 'http://technobrave.com/'
code: ''
form:
fields:
site_logo:
label: Site Logo
comment: The website logo as it should appear on the front-end
type: fileupload
mode: image
imageHeight: 32
imageWidth: 443
As you can see i have added a Site Logo label through which admin can upload a logo and i will show it up front, which is working fine as i am able to show logo at front area like this.
menu.htm
{% if this.theme.site_logo %}
<img src="{{ this.theme.site_logo.path }}" width="100%" height="auto"/>
{% else %}
<img src="{{ 'assets/images/logo.png'|theme }}" width="100%" height="auto"/>
{% endif %}
But the thing is i am also creating an api and i want to do the same thing in that api. This is what i am trying.
routes.php
use System\Classes\SettingsManager;
/* API to get Website Logo Dynamically Starts */
Route::post('/getWebsiteLogo', function ()
{
$settings = Settings::instance();
print_r($settings);
});
/* API to get Website Logo Dynamically Ends */
But i am having an error saying
Class 'Settings' not found
Can someone guide me or suggest me how can i accomplish the same thing, or say how to get the dynamic website logo in one of my apis ?
Thanks
Ok guys, thanks for your support .. eventually i have worked around like this.
routes.php
<?php
use Cms\Classes\ComponentBase;
use RainLab\Pages\Classes\Router;
use Cms\Classes\Theme;
/* API to get Website Logo Dynamically Starts */
Route::post('/getWebsiteLogo', function ()
{
$theme = Theme::getActiveTheme();
$logo_url = '';
if($theme->site_logo['attributes']['disk_name'])
{
echo $theme->site_logo->path;
}
}
?>
Thanks for help and support. Highly appreciated.