want to convert render html to nunjucks with variable and every thing - nunjucks

becuase i want to manuplate/add some html tags after html render and save into nunjucks (like before rendering);
nunjucks before render
<div class="ps-4">
<h1>{{heading}}</h1>
{% if isShowLi %}
<div class="px-4">
{% for item in items %}
<div>{{item.name}}</div>
{% endfor %}
</div>
{% endif %}
</div>
nunjucks after render and html modification
<div class="ps-4">
<h1>hello world</h1>
<img src="abc.png" />
<div class="px-4">
<div>item 1</div>
<div>item 2</div>
<div>item 3</div>
<div>item 4</div>
<div>item 5</div>
</div>
</div>
and i want it like that
<div class="ps-4">
<h1>{{heading}}</h1>
<img src="abc.png" />
{% if isShowLi %}
<div class="px-4">
{% for item in items %}
<div>{{item.name}}</div>
{% endfor %}
</div>
{% endif %}
</div>
please solve and suggest any way to do this thing pleassssss

If you want the output to look like the original nunjucks logic you typed in, then you can try the following technique. On your HTML template within your nunjucks project...
<pre>
<code>
<div class="ps-4">
<h1>{{heading}}</h1>
<img src="abc.png" />
{% if isShowLi %}
<div class="px-4">
{% for item in items %}
<div>{{item.name}}</div>
{% endfor %}
</div>
{% endif %}
</div>
</code>
</pre>

Related

Display Only the Most Recent Post by Category in Jekyll

I have posts within my blog that have 2 categories: project, and then whatever the name of the project is (i.e. project1 and project2). I've built out a page to display all my projects, with a loop that looks like this:
<div class="container">
{% for post in site.categories.project %}
{% assign remainder = forloop.index | modulo: 3 %}
{% if remainder == 1 or forloop.first %}
<div class="row">
{% endif %}
<div class="col-sm-4 d-flex align-items-stretch">
<div class="card" href="{{ site.baseurl }}{{ post.url }}">
<div class="m-2">
<h3>{{post.title}} {{post.categories[1]}}</h3>
{% if post.image %}
<img src="{{ post.image }}" />
{% endif %}
<p>{{post.projectInfo}}</p>
</div>
<div class="m-2 mt-auto">
{% if post.projectLink %}
Project Link |
{% endif %}
Blog Post
</div>
</div>
</div>
{% if remainder == 0 or forloop.last %}
</div>
{% endif %}
{% endfor %}
</div>
However, when I make an update to the project, I'd like to ONLY display the most recent post, and skip over all the others. I've tried assigning a variable thisProject, and then doing a limit: 1, but because I've grabbed each post already in the outermost for loop, it'll actually show multiple iterations of lastest post for the project that has multiple posts.
Any way I can better limit this?

How can I render a template inside asyncEach in nunjucks

{% asyncEach example in component.examples %}
{% include "./example.njk" %}
{% endeach %}
// example.njk
<article class="spectrum-CSSExample">
<h3 id="{{example.slug}}" class="spectrum-CSSExample-heading spectrum-Heading spectrum-Heading--sizeS">
{{example.name}}
<div class="{{ spectrum-StatusLight spectrum-StatusLight--sizeM spectrum-CSSExample-status spectrum-StatusLight--{{ util.getStatusLightVariant(example.status) }}">
{{example.status}}
</div>
</h3>
{# {% include "./exampleContent.njk" %} #}
</article>
In example.njk example is undefined. How can I pass example inside a include like this?
example is always undefined inside example.njk

Loop through liquid advanced custom field to return multiple metafield values

I've built the following liquid for loop to retrieve & output data from a repeating advanced custom field in Shopify. The ACF namespace is faq, and contains heading and content data. My current loop is as follows:
<div class="feed-faqs">
{% if page.metafields.faq != blank %}
{% assign faqs = page.metafields.faq %}
{% for item in faqs %}
{% assign i = forloop.index %}
<div class="item item--{{ i }}">
{{ heading[i] }}
{{ content[i] }}
</div>
{% endfor %}
{% endif %}
</div>
However, on the frontend, this loop returns the following:
<div class="feed-faqs">
<div class="item item--1">
</div>
<div class="item item--2">
</div>
</div>
Is what I'm trying to achieve (to output multiple values from a repeating ACF field) possible with this approach, and if so, where have I gone wrong in fetching the header & content data?
Worked it out, so leaving this answer for anyone else in the future:
<div class="feed--faqs">
{% if page.metafields.faq != blank %}
{% assign faqs = page.metafields.faq.heading %}
{% for value in faqs %}
{% assign i = forloop.index0 %}
<div class="item item--{{ i }}">
<h4>{{ page.metafields.faq.heading[i] }}</h4>
<p>{{ page.metafields.faq.content[i] }}</p>
</div>
{% endfor %}
{% endif %}
</div>
Metafield value type is set to 'Json String'.
For reference, I'm using the ArenaCommerce Advanceds Custom Fields app: https://apps.shopify.com/advanced-custom-field.

sorting front matter from markdown file

i'm fairly new to jekyll, but i'm really loving the things you're able to do with it, and the speed for deployment.
so, my site is managed with siteleaf and deployed to github pages. right now, i'm working to build out pages to showcase my past projects, and i need to be able to create dynamic content- have the ability to add multiple meta fields with the same names i.e. multiple fields called center_image or text_block that i can display based on their sort order in the admin panel/markdown file that is creating the page. here's the code i've written so far, it's currently showing the content correctly, but it doesn't allow me to 1. have multiple iterations of the same meta field or 2. sort the content dynamically.
{% for photo in page.project_content.full_width_image %}
<div class="fullwidth-image content-block">
<img src="{{ photo }}">
</div>
{% endfor %}
{% for photo in page.project_content.center_image %}
<div class="center-image content-block">
<img src="{{ photo }}">
</div>
{% endfor %}
{% for photo in page.project_content.split_left_image %}
<div class="split-image-left content-block">
<img src="{{ photo }}">
</div>
{% endfor %}
{% for photo in page.project_content.split_right_image %}
<div class="split-image-right content-block">
<img src="{{ photo }}">
</div>
{% endfor %}
{% for content in page.project_content.text_content %}
<div class="text-block content-block">
{{ content | markdownify }}
</div>
{% endfor %}
so, to sum up, i need to be able to sort this content and also include multiple iterations of the same content type. does anyone have any ideas?
thanks!
jesse
after contacting support, here's what i found.
first, i needed to change the YAML front matter from being key fields to object fields. this creates an array of content, like so
project_content:
- type: full-width-image
image: "/uploads/hero.jpg"
- type: text
body: This is another test content block.
- type: text
body: text two.
then, my markup is like so...
{% for block in project.content %}
{% case block.type %}
{% when 'full_width_image' %}
<img src="{{ block.image }}">
{% when 'text' %}
{{ block.text | markdownify }}
{% endcase %}
{% endfor %}
and my output becomes:
<div class="full-width-image content-block">
<img src="/uploads/hero.jpg">
</div>
<div class="text content-block">
<p>This is another test content block.</p>
</div>
<div class="text content-block">
<p>text two.</p>
</div>
this is exactly what i needed to do, and i can change the sort order of the items in my siteleaf admin!

Shopify show how close to free shipping

I am trying to show how close someone is to free shipping using the standard timber draw cart system. The code should be checking if the customer has $30 or less and then display how much more they need to spend to achieve free shipping, and if they are over $30 state that they have achieve the free shipping threshold.
Here is my current cart code
<!-- /snippets/ajax-cart-template.liquid -->
{% comment %}
This snippet provides the default handlebars.js templates for
the ajax cart plugin. Use the raw liquid tags to keep the
handlebar.js template tags as available hooks.
{% endcomment %}
<script id="CartTemplate" type="text/template">
{% raw %}
<form action="/cart" method="post" novalidate class="cart ajaxcart">
<div class="ajaxcart__inner">
{{#items}}
<div class="ajaxcart__product">
<div class="ajaxcart row" data-line="{{line}}">
<div class="grid__item desktop-4 tablet-2 mobile-1">
<img src="{{img}}" alt="">
</div>
<div class="desktop-8 tablet-4 mobile-2">
<p>
{{name}}
{{#if variation}}
<span class="ajaxcart__product-meta">{{variation}}</span>
{{/if}}
{{#properties}}
{{#each this}}
{{#if this}}
<span class="ajaxcart__product-meta">{{#key}}: {{this}}</span>
{{/if}}
{{/each}}
{{/properties}}
{% endraw %}{% if settings.cart_vendor_enable %}{% raw %}
<span class="ajaxcart__product-meta">{{ vendor }}</span>
{% endraw %}{% endif %}{% raw %}
</p>
<p><strong>{{{price}}}</strong></p>
<div class="display-table">
<div class="display-table-cell">
<div class="ajaxcart__qty">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--minus quantity-increment" data-id="{{id}}" data-qty="{{itemMinus}}" data-line="{{line}}">
<span>−</span>
</button>
<input type="text" name="updates[]" class="ajaxcart__qty-num" value="{{itemQty}}" min="0" data-id="{{id}}" data-line="{{line}}" aria-label="quantity" pattern="[0-9]*">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--plus quantity-increment" data-id="{{id}}" data-line="{{line}}" data-qty="{{itemAdd}}">
<span>+</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
{{/items}}
{% endraw %}{% if settings.cart_notes_enable %}{% raw %}
<div>
<label for="CartSpecialInstructions">{% endraw %}{{ 'cart.general.note' | t }}{% raw %}</label>
<textarea name="note" class="input-full" id="CartSpecialInstructions">{{ note }}</textarea>
</div>
{% endraw %}{% endif %}{% raw %}
</div>
<div class="ajaxcart__footer row">
<div class="desktop-half tablet-half mobile-half">
<p><strong>{% endraw %}{{ 'cart.general.subtotal' | t }}{% raw %}</strong></p>
</div>
<div class="desktop-half tablet-half mobile-half">
<p class="text-right"><strong>{{{totalPrice}}}</strong></p>
</div>
<p class="text-center">{% endraw %}{{ 'cart.general.currency_disclaimer' | t }}{% raw %}</p>
<p class="text-center">{% endraw %}{{ section.settings.hello }}{% raw %}</p>
<p class="text-center">{% endraw %}{{ 'cart.general.shipping_at_checkout' | t }}{% raw %}</p>
<p class="text-center">
{% endraw %}
{% if totalPrice <= 30 %}
You’re just {{{30 | minus: totalPrice}}} away from FREE shipping.
{% else %}
You've qualified for Free Shipping.
{% endif %}
{% raw %}
</p>
<button type="submit" class="cart__checkout" name="checkout">
{% endraw %}{{ 'cart.general.checkout' | t }}{% raw %} →
</button>
{% endraw %}{% if additional_checkout_buttons %}
<div class="additional_checkout_buttons">{{ content_for_additional_checkout_buttons }}</div>
{% endif %}{% raw %}
</div>
</form>
{% endraw %}
</script>
<script id="AjaxQty" type="text/template">
{% raw %}
<div class="ajaxcart__qty">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--minus icon-fallback-text" data-id="{{id}}" data-qty="{{itemMinus}}">
<span class="icon icon-minus" aria-hidden="true"></span>
<span class="fallback-text">−</span>
</button>
<input type="text" class="ajaxcart__qty-num" value="{{itemQty}}" min="0" data-id="{{id}}" aria-label="quantity" pattern="[0-9]*">
<button type="button" class="ajaxcart__qty-adjust ajaxcart__qty--plus icon-fallback-text" data-id="{{id}}" data-qty="{{itemAdd}}">
<span class="icon icon-plus" aria-hidden="true"></span>
<span class="fallback-text">+</span>
</button>
</div>
{% endraw %}
</script>
<script id="JsQty" type="text/template">
{% raw %}
<div class="js-qty">
<button type="button" class="js-qty__adjust js-qty__adjust--minus quantity-increment" data-id="{{id}}" data-qty="{{itemMinus}}">
<span>−</span>
</button>
<input type="text" class="js-qty__num" value="{{itemQty}}" min="1" data-id="{{id}}" aria-label="quantity" pattern="[0-9]*" name="{{inputName}}" id="{{inputId}}">
<button type="button" class="js-qty__adjust js-qty__adjust--plus quantity-increment" data-id="{{id}}" data-qty="{{itemAdd}}">
<span>+</span>
</button>
</div>
{% endraw %}
</script>
You wrote:
{% endraw %}
{% if totalPrice <= 30 %}
You’re just {{{30 | minus: totalPrice}}} away from FREE shipping.
{% else %}
You've qualified for Free Shipping.
{% endif %}
{% raw %}
Which is correct... if you were offering free shipping at $0.30
Shopify stores prices as integers, not floating-point-numbers - so the values in the price variables represent cents, not dollars. If you want to compare to $30.00, you'll need to compare to 3000, not 30
Also, you've put your Liquid code into a Handlebars template - Liquid is rendered server-side, so the evaluation of the cart total happens before the page is served to your client. If the shopper changes their cart total, the template does not get re-evaluated at the server level, so the message won't be dynamic.
What you should do instead is add a new variable to your template, like {{{ shippingMessageHTML }}}, then edit the script file that populates the template to have a variable with the same name.
Example:
(Note: It looks like you're using Brooklyn or one of its related themes. This theme family names the function that populates that template buildCart, which is usually found in an asset file named ajax-cart, app or theme. The extension will either be .js or .js.liquid)
Find the section of code near the bottom of the function, which should look something like this:
// Gather all cart data and add to DOM
data = {
items: items,
note: cart.note,
totalPrice: Shopify.formatMoney(cart.total_price, settings.moneyFormat),
totalCartDiscount: cart.total_discount === 0 ? 0 : {{ 'cart.general.savings_html' | t: savings: '[savings]' | json }}.replace('[savings]', Shopify.formatMoney(cart.total_discount, settings.moneyFormat))
};
At the end of that data object, add your message HTML. Example:
// Gather all cart data and add to DOM
data = {
items: items,
note: cart.note,
totalPrice: Shopify.formatMoney(cart.total_price, settings.moneyFormat),
totalCartDiscount: cart.total_discount === 0 ? 0 : {{ 'cart.general.savings_html' | t: savings: '[savings]' | json }}.replace('[savings]', Shopify.formatMoney(cart.total_discount, settings.moneyFormat)),
//Note: we added a comma after the previous line before adding this new one
shippingMessageHTML: cart.total_price < 3000 ? 'Want free shipping? It\'s only ' + Shopify.formatMoney(3000 - cart.total_price, settings.moneyFormat) + ' away!' : 'Yahoo! No pay-for-shipping for you!'
};
With that, when the data gets merged with your cart template, the most current cart total will be used in the calculation. As long as the variable you use inside the data object matches the name of the variable you set in the CartTemplate, you'll be good to go!
(If you're wondering what the difference between {{ variable }} and {{{ variable }}} is, the Handlebars template language interprets double-curly-braces as text and triple-curly-braces as HTML. So if you want to put a span or anything into your message, use triple braces. If your message will only ever be flat text, you can use either double or triple)

Resources