liquid schema works, but removes the section when modified from the editor - shopify

I am new to the entire Shopify and liquid environment. However I was able to modify a section that used the {%schema%} tag to display a control to set a background and the maximum width of a text box.
So I ventured to create a section for myself to add a small FAQ block on one of the pages.
I have read everything I can to make sure that I am not forgetting anything, I have also checked the code on existing sections that work correctly, and I cant find the reason for this issue.
when I open the page with the section in it in the Theme editor, I loads correctly and displays the default color. I also see the modifier block on the left pane, however as soon as I change the value in the editor, it simply makes the entire section disappear.
can somebody help me to point out what am I doing wrong?
thank you very much
this is the entire code in the section:
<style>
.faq{
max-width:900px;
width:80%;
}
.faq-container{
background-color:{{section.settings.container_background_color}};
display: flex;
justify-content:center;
}
</style>
<div class="faq-container">
<div class="faq" id="ndnappseasyfaqs-wrapper"></div>
</div>
{%schema%}
{
"name": "FAQ section",
"settings": [
{
"type": "color",
"id": "container_background_color",
"label": "Background color",
"default": "#a0cf67"
}
]
}
{% endschema %}
this is the result before I try to modify it:
before modification
this is the result as soon as I modify the color:
After modification

This might be an issue linked to preview update in JS.
Did you try to save your changes and see if it works?

According to Integration with the theme editor,
When merchants customize sections, the HTML of those sections is dynamically added, removed, or re-rendered directly onto the existing DOM without reloading the entire page.
JavaScript that runs when the page loads will not run again when a section is re-rendered or added to the page. This poses a problem for any custom scripts that would need to be re-run.
If you're running some js on page load, it won't be run again after the user makes a change in section. So I guess you have to run the js manually. Just bind the event with your event listener
document.addEventListener('shopify:section:load', function(event){
[your code...]
});

Related

Docusaurus: add custom button to code block?

I’m testing to use Docusaurus for a tutorial and documentation site. I want to customize the code block in markup (md or mdx) to for example add an edit button inside the code block that will open the code in plnkr.
My question is, how can I add a button (or several buttons) in the code block and add click events to the buttons?
I have tested Eleventy https://www.11ty.dev/ recently and in that I used markdown-it-attrs to add attributes in markdown.
const markdownIt = require("markdown-it");
const markdownItAttrs = require("markdown-it-attrs");
and then in the markdown I could add attributes to a code block indicating if that should have an edit button or not.
```js {edit=yes}
let a = 2;
console.log(a);
```
And then in a script find this code block and add a button and an event listener.
.hasAttribute("edit")
.insertAdjacentHTML("afterbegin", `<button style="float: right;" class="code_edit">Edit</button>`);
.addEventListener("click", () => {
I have tried doing something similar in Docusaurus by adding a script in docusausrus.config.js
scripts: [{ defer: true, src: "/mycustom.js" }],
I can see that this script is added in the head but the script can’t find any html elements. I don’t know where to start with adding attributes to the markup.

JSON content shows a blank window for Tiptap-Vuetify?

Background
I'm using tiptap-vuetify to implement a message/chat UI where users see an editable Tiptap instance for creating new messages as well as several uneditable Tiptap instances (one for each already-sent message in the thread the user is viewing).
I have the editable instance output data in JSON format, which I store in my database in a JSONB field.
Problem
When I load the JSON for sent messages from the database, only plaintext messages show up; if I applied any kind of styling (bold, italics, lists, etc.), nothing at all shows up.
The code I'm using for the uneditable Tiptap instances is this:
<tiptap-vuetify
v-model="message.content"
:editor-properties="{ editable: false }"
output-format="json"
/>
Here's a screenshot of the message object (and message.content) for the "bold asdf" example above:
When i was looking in the documentation -> Get started
I see that the content is HTML.
As it usually is inside any tiptap.
Your content data is an object with alot of nested data. I don't think the plugin/component can handle that type of format.
Try save your data as HTML to your .json and there for also fetch the data as HTML from your .json.
Example:
{
messages: [
{
"id": 1,
"content": "<p>foo bar</p>"
},
{
"id": 2,
"content": "<p>hello world</p>"
},
]
}
(New to answer questions on stackoverflow)
I figured out the fix:
I didn't realize I needed to include the :extensions prop for all of the HTML features I wanted to use (bold, italic, etc.) in the editor that would render the HTML. I thought those extensions were just used to add the toolbar buttons, but they are also used to render the JSON that those buttons produce.
To then hide the toolbar, I just used the example toolbar-slot code from the readme, and the toolbar was gone.
Here's the working code:
<tiptap-vuetify
v-model="message.content"
:extensions="extensions"
:editor-properties="{ editable: false }"
>
<template #toolbar="{ buttons }">
<pre>{{ buttons }}</pre>
</template>
</tiptap-vuetify>

Is it possible to test scroll in using Gemini by Yandex?

Does anyone use Gemini by Yandex for testing css regression?
I faced with the following problem: need to test scroll in some page, but as I know, gemini capture whole page and show only that part which you set by adding .setCaptureElements('someElement').
E.g. I set capture element as html (which has 100% height) and my content is very huge, but gemini screenshot show up only cut over part of page without possibility to scroll cause page hasn't scroll as such...
Maybe some of you faced with same problem and have cool solution?
Thanks!
I had the necessity to make a screenshot of the page that has scrolling. I need the screenshot of the whole page and made changes which let me did it:
Used .setCaptureElements only for the element where is scrolling exist (not the whole body).
Added line compositeImage: true in configuration file.
gemini.suite('App-Name', function(test) {
test.setUrl('/')
.setCaptureElements('body')
.capture('Full Page', (actions) => actions.wait(2000))
});
//You can also use
.setCaptureElements('html') , if .setCaptureElements('body') is not working perfect for you.
You need to add this code in .gemini.js
browsers: {
'chrome-desktop': {
desiredCapabilities: {
browserName: 'chrome',
compositeImage: true,
screenshotMode: 'fullpage',
}
}

Dynamic menu button items in TinyMCE

I have a custom menubutton in my tinyMCE editor that uses specific HTML elements elsewhere on the page as the menu items. I use a jQuery selector to get the list of elements and then add one each as a menu item:
c.onRenderMenu.add(function(c,m) {
m.add({ title: 'Pick One:', 'class': 'mceMenuItemTitle' }).setDisabled(1);
$('span[data-menuitem]').each(function() {
var val = $(this).html();
m.add({
title: $(this).attr("data-menuitem"),
onclick: function () { tinyMCE.activeEditor.execCommand('mceInsertContent', false, val) }
});
});
});
My problem is that this only happens once when the button is first clicked and the menu is first rendered. The HTML elements on the current page will change occasionally based on user clicks and some AJAX, so I need this selector code to run each time the menu is rendered to make sure the menu is fully up-to-date. Is that possible?
Failing that, is it possible to dynamically update the control from the end of my AJAX call elsewhere in the page? I'm not sure how to access the menu item and to update it. Something using tinyMCE.activeEditor.controlManager...?
Thanks!
I found a solution to this problem, though I'm not sure it's the best path.
It doesn't look like I can make tinyMCE re-render the menu, so instead I've added some code at the end of my AJAX call: after it has updated the DOM then it manually updates the tinymce drop menu.
The menu object is accessible using:
tinyMCE.activeEditor.controlManager.get('editor_mybutton_menu')
where mybutton is the name of my custom control. My quick-and-dirty solution is to call removeAll() on this menu object (to remove all the current menu items) and then to re-execute my selector code to find the matching elements in the (new) DOM and to add the menu items back based on the new state.
It seems to work just fine, though tweaks & ideas are always welcome!

Change dynamically the stylesheet depending on document mode

is there a way to change stylesheet file dynamically depending on if the document is in edit or read mode?
What I would like to do is to add the following code to the "compute value" option of the resource href property:
if(document.isEditable()){
return "style_edit.css"
}
else{
return "style_read.css"
}
My main problem with this is that when the page loads, it gives the error "document not found". This is probably because when the page loads, there is only a view that includes the documents and when the user clicks a document id, then the custom control with the binded document appears. I don't know how to make the binded to custom control document available on load of the page.
Edited:
I tried a try/catch block and now the xpage opens without displaying an error. But although the custom control is refreshed, the css file does not change, althoug I use compute dynamically and not compute on load
Thank you in advance!
You can set the resource href attribute as computed. For this go to All Properties of XPage "basics > resources > styleSheet". Here you can compute the href attribute with your JavaScript code. So your resource in XPage source would look something like this
<xp:this.resources>
<xp:styleSheet>
<xp:this.href><![CDATA[#{javascript:if (document.isEditable()) {
return "style_edit.css";
} else {
return "style_read.css";
}}]]></xp:this.href>
</xp:styleSheet>
</xp:this.resources>
To access the data source from custom control you can use the global variable currentDocument instead of document.
Why force user to download separate files on edition when You can simply add computed styleClass to some panel/component:
<xp:panel>
<xp:this.styleClass><![CDATA[#{javascript:return document.isEditable()?"docEditMode":"docReadMode";}]]></xp:this.styleClass>
</xp:panel>
and use it as a selector inside style.css