Append Collections.Liquid file through public app - shopify-app

I am a PHP Developer and, I am trying to append the theme functionality of any Shopify Theme, Though Public App. I did that by opening the theme file but now I want to implement that functionality through an app.

I believe you want to change theme code via API like in this page
First use GET /admin/api/2019-07/themes.json to see which theme shop is using. Check if "role" : "main" then take the theme id.
After get the id, you can send a json to PUT /admin/api/2019-07/themes/{theme_id_from_step_one}/assets.json to alter the file in the code without open it.
{
"asset": {
"key": "templates/index.liquid", // file location
"value": "<img src='backsoon-postit.png'><p>We are busy updating the store for you and will be back within the hour.</p>" //delete liquid code inside and put those code in
}
}
In case you only want to append the code. You must use GET /admin/themes/828155753/assets.json?asset[key]={file_location} . It gives
{
"asset": {
"key": "templates/index.liquid",
"public_url": null,
"value": "<!-- LIST 3 PER ROW -->\n<h2>Featured Products</h2>\n<table id=\"products\" cellspacing=\"0\" cellpadding=\"0\">\n {% tablerow product in collections.frontpage.products cols:3 %}\n {{ product.featured_image | product_img_url: 'small' | img_tag }}\n <h3>{{product.title}}</h3>\n <ul class=\"attributes\">\n <li><span class=\"money\">{{product.price_min | money}}</span></li>\n </ul>\n {% endtablerow %}\n</table>\n<!-- /LIST 3 PER ROW -->\n\n{{ content_for_index }}\n\n<div id=\"articles\">\n {% assign article = pages.frontpage %}\n <div class=\"article\">\n {% if article.content != \"\" %}\n <h3>{{ article.title }}</h3>\n <div class=\"article-body textile\">\n {{ article.content }}\n </div>\n {% else %}\n <div class=\"article-body textile\">\n In <em>Admin > Blogs & Pages</em>, create a page with the handle <strong><code>frontpage</code></strong> and it will show up here.\n <br />\n {{ \"Learn more about handles\" | link_to \"http://wiki.shopify.com/Handle\" }}\n </div>\n {% endif %}\n </div>\n</div>\n",
"created_at": "2010-07-12T15:31:50-04:00",
"updated_at": "2010-07-12T15:31:50-04:00",
"content_type": "text/x-liquid",
"size": 1068,
"theme_id": 828155753
}
}
take the value and use regex to append.

Related

Shopify Theme Development - Section and Block development

Hello Shopify Theme Development Pros,
I am trying to add a block in a section of my theme and although the input block shows up on the screen, when I input type nothing shows up on the actual website. I have tried defining styles in CSS as well, but no luck.
This is what I have added to the block settings in the liquid file...
{
"type": "text",
"id": "review_title",
"label": "Review Heading",
"default": "Enter title here"
},
And this is the html that I added...
<div class="testimonial-heading> {% if section.settings.review_title != blank %} <p> {{ section.settings.review_title | escape }} </p> {% endif %}</div>
When you are using blocks you need to loop them since there are dynamic content that can be added multiply times.
So at the moment you are targeting the settings object and not the blocks section.settings.review_title.
In order to list the blocks you need to do the following:
{% for block in section.blocks %}
<div class="testimonial-heading">
{% if block.settings.review_title != blank %}
<p> {{ block.settings.review_title | escape }} </p>
{% endif %}
</div>
{% endfor %}

Explanation about data-apos-ajax-append outside pieces-pages

I want to implement the apostrophes Ajax features in my project but sadly I don't understand the Ajax functions not completely. I have been studying the documentation for the last week now but i don't find enough information about that topic. I want kindly ask if it's possible to use data-apos-ajax-append outside of apostrophe-pieces-pages
I created a widget like that:
lib/modules/infinite-widgets/index.js
module.exports = {
extend: 'apostrophe-widgets',
label: 'Infinite Widget',
addFields: [
{
name: 'posts',
label: 'Posts',
type: 'array',
titleField: 'name',
schema: [
{
name: 'name',
type: 'string',
label: 'Name'
},
{
name: '_image',
type: 'joinByOne',
withType: 'apostrophe-image',
label: 'Image',
required: true,
filters: {
projection: {
attachment: 1,
description: 1,
title: 1
}
}
}
]
}
]
};
lib/modules/infinite-widgets/views/widget.html
<div class="row margin">
<div class="col s12 m12">
<div class="radius
{% if data.widget.shadowOn == true %}
z-depth-1
{% endif %}
">
<div data-apos-ajax-context="infinite">
{% include "indexAjax.html" %}
</div>
</div>
</div>
</div>
lib/modules/infinite-widgets/views/indexAjax.html
<div data-apos-ajax-append>
{% for name in data.widget.posts %}
{% set image = apos.images.first(name._image) %}
<div class="card z-depth-0" style="
{%- if piece.backColor-%}
background-color:{{ piece.backColor }}
{% endif %}
">
<div class="card-image">
<img src="{{ apos.attachments.url(image, { size: 'one-sixth' }) }}" />
</div>
<div class="card-content">
{{ name.name }}
</div>
</div>
{% endfor %}
</div>
That is working pretty nice but unfortuantly It displays all posts created simultansiosly and I wasen't able to use the "Load More..." button with AJAX here
{# Load More button. Also outside data-apos-ajax-append, so it gets refreshed #}
{% if data.currentPage < data.totalPages %}
{# "Load More" button with the "append=1" flag #}
Load More...
{% endif %}
So can I modify this query, to have a load more button, or even better data-apos-ajax-infinite-scroll for content of an array created in an widget instead of an piece?
No, it is not possible to do that using data-apos-ajax-append. That feature is specifically for apostrophe-pieces-pages and there is no back end implementation waiting to talk to it for widgets, for instance.
You should instead look at writing a browser-side widget player for your widget, which gives you a place to make your own API calls back to the server. You can see that technique in the source of the apostrophe-twitter-widgets module.

Calling Api within nunjucks file

I am very newbie in nunjucks.
{% set projects = [
{
id: 3,
dbaslik: "some data 1",
ddetay: "some data 1",
src: "img/someimg1.png"
},
{
id: 4,
dbaslik: "some data 2",
ddetay: "some data 2",
src: "img/someimg2.png"
},
.....
] %}
<div class="owl-one owl-carousel owl-theme">
{% for project in projects %}
<div class="item-proje"
id="project-image-slider-{{proje.id}}"
data-baslik="{{project.dbaslik}}"
data-detay="{{project.ddetay}}" >
<img src="{{project.src}}"/>
</div>
{% endfor %}
</div>
This is what my own template which is used to populate some projects. But this is just static data as you see. I have to work with real data. So
I need to call specific project api and get projects, assign project variable and populate them using nunjucks? How can I do that?

How to display data from Jekyll data file based on current page variable

The Problem
I have a div on my Jekyll site where I would like to display data that is generated from _data/book-data.yml, for example:
- name: johnson-everything-under
title: Everything Under
author: Daisy Johnson
publisher: Faber & Faber
pub-date: 12/12/2012
- name: johnson-train-dreams
title: Train Dreams
author: Denis Johsnon
publisher: Granta
pub-date: 01/01/2001
I'm trying to find a way to display the data that corresponds to the relevant page (each book entry has a different page), and I thought maybe this would be possible if the name key corresponds to the page.url, or some other page variable.
What I've tried
On a working page, I have an include which contains the following HTML:
<div class="book-meta">
{% if page.category == "reviews"%}
<div class="book-thumbnail">
<img class="post-thumbnail-lg" src="{{ site.baseurl }}/assets/images/{{ page.thumbnail }}" alt="{{ page.thumbnail }}">
</div>
{% for book in site.data.book-data %}
<div class="book-details">
<ul class="book-meta-list">
<li class="book-meta-item"><p>{{ book.author }}</p></li>
<li class="book-meta-item"><p><em>{{ book.title }}</em></p></li>
<li class="book-meta-item"><p>{{ book.publisher }}</p></li>
<li class="book-meta-item"><p>{{ book.pub-date }}</p></li>
</ul>
</div>
{% endfor %}
{% endif %}
</div>
The CSS is not important, but as it is currently the output of the above HTML is:
Desired output
As you can see, the output contains both the blocks of metadata from the .yml file. I would like to find a way so that only the relevant block of data (the first block in this instance) is displayed:
Potential solution(s)
I thought that there might be a way of matching a page.variable to the YAML block name so only the right book data gets output. Something along the lines of:
{% assign url_substring = page.url | split, '/' | last %}
// url_substring = johnson-everything-under
{% for book in site.data.book-data %}
{% if url_substring == book.name %}
// = true
<p>{{ book.title }}<p>
{% endif %}
{% endfor %}
Other than the fact that I can't get this to work properly, I can also see that the liquid tag {{ book.title }} has no way of knowing which book title to output, even if the page.url matches.
I'm not sure if I'm on the right track here, so if anyone has any other suggestions on how this might be achievable, I'd love to hear it. Thanks in advance.
You can use Jekyll's where filter coupled with a smart include:
{% assign book = site.data.book-data | where: 'title', include.title | first %}
<div class="book-meta">
<div class="book-thumbnail">
<img
class="post-thumbnail-lg"
src="{{ book.thumbnail | prepend: 'assets/images/' | relative_url }}"
alt="{{ book.title }}"
/>
</div>
<div class="book-details">
<ul class="book-meta-list">
<li class="book-meta-item"><p>{{ book.author }}</p></li>
<li class="book-meta-item"><p><em>{{ book.title }}</em></p></li>
<li class="book-meta-item"><p>{{ book.publisher }}</p></li>
<li class="book-meta-item"><p>{{ book.pub-date }}</p></li>
</ul>
</div>
</div>
Note that I also included thumbnail info in the data file..
Then just pass the title parameter to the include (in the layout for your book's page):
{% include books.html title = 'Everything Under' %}
If you'd like to render a "listing", then just loop through and render:
{% for book in site.data.book-data %}
{% include books.html title = book.title %}
{% endfor %}

Post without title in Jekyll

In my Jekyll blog, I would like some posts not to have a title. How could I modify the Jekyll codebase to make it so that posts do not require a title?
You don't need to alter the jekyll codebase to remove titles. That can be done using different layouts with appropriate liquid filters and tags.
For individual post pages, simply make a new layout file (e.g. "_layouts/no-title-post.html") that doesn't have the {{ page.title }} liquid tag. In your _posts source file, set the YAML front matter to call it. For example:
---
layout: no-title-post
---
Note here that "title:" isn't required in the YAML front matter. If jekyll needs it, the value will be automatically crated from the filename. For example, "_posts/2012-04-29-a-new-post.md" would have its title variable set to "A New Post" automatically. If your templates don't call the title tags, it won't matter. You could include a "title:" in the front matter and it simply wouldn't be displayed.
You can also display the page without the title in your listing/index pages. Check the posts layout to determine if the title should be displayed. For example, to show titles on all your pages except ones that have the 'no-title-post' layout, you would do something like this:
{% for post in paginator.posts %}
{% if post.layout != 'no-title-post' %}
<h1>{{ post.title }}</h1>
{% endif %}
<div class="postContent">
{{ post.content }}
</div>
{% endfor %}
In that case, the link to the page itself is also removed. If the page needs to be addressable, you would have to add the link back in somewhere else.
edemundo's solution doesn't work anymore in all cases with Jekyll 3.
I use an empty title as default:
defaults:
-
scope:
type: "posts"
values:
layout: "post"
title: ""
Then you can compare titles against the empty string in your layouts, for example:
{% if post.title == "" %}
{{ post.content | strip_html | truncatewords:5 }}
{% else %}
{{ post.title }}
{% endif %}
If you like the automatic title generation you can use as frontmatter:
---
title: ""
---
I was having the same doubt, then I stumbled on this really simple solution:
{% if post.title %}
<h1>{{ post.title }}</h1>
{% endif %}
And then in the post file itself you would leave the title variable empty:
---
layout: post
title:
---
This way, the h1 will not print if the title is empty. I found this method particularly useful for post types like quotes, which most of the time doesn't have titles.

Resources