We are currently installing blogs on our Dynamics 365 Portal.
Wanting to modify the layout of the posts we recreacted a template based on this structure : https://community.adxstudio.com/products/adxstudio-portals/documentation/configuration-guide/liquid-templates/objects/blogs/
Because the adx "post" object doesn't contain tags, we had to use a fetchxml query to get them.
The problem is the query retrieve all the tags :
Only the Général tag should be showing on the first post only.
Full code :
{% assign blog = blogs['Actualités et annonces'] %}
{% assign posts = blog.posts %}
<div class="col-md-8">
<div class="content-panel panel panel-default">
<div class="panel-heading">
{% assign sitemarker = sitemarkers["Blog Home"] %}
{% assign snippet = snippets["Home Blog Activity Heading"] %}
<a class="pull-right" href="{{sitemarker.url}}"> All Blogs </a>
<h4>
<a class="feed-icon fa fa-rss-square" href="{{ blogs.feedpath }}">
{{ snippet.adx_value }}
</a><div class="grid-container">
{% for post in posts.all %}
<div class="grid-item">
<a class="image-header" href="{{ post.url }}">
{% if post.new_category %}
{% assign category = entities.new_vignette[post.new_category.id] %}
{% assign imgpath = category.new_path %}
{% elsif post.new_vignette %}
{% assign imgpath = post.new_vignette %}
{% else %}
{% assign imgpath = "../pocfabien/avarap-entete" %}
{% endif %}
<img class="img-responsive img-post" src="{{imgpath}}">
</a>
<div class="content-header">
<h4 class="list-group-item-heading">
{{ post.title }}
</h4>
<br />
<abbr>{{ post.publish_date }}</abbr>
</div>
<div class="content-preview">
{{post.adx_summary}}
</div>
<div>
{% fetchxml tags %}
<fetch>
<entity name="adx_tag">
<attribute name="adx_name" />
<attribute name="adx_tagid" />
<link-entity name="adx_blogpost_tag" from="adx_tagid" to="adx_tagid" intersect="true">
<filter>
<condition attribute="adx_blogpostid" operator="eq" value="{{ post.adx_blogpostid }}" />
</filter>
</link-entity>
</entity>
</fetch>
{% endfetchxml %}
{% for tag in tags.results.entities %}
{{ tag.adx_name }}
{% unless forloop.last %} | {% endunless %}
{% endfor %}
</div>
<img class="plusign" src="plusign.png">
</div>
{% endfor %}
</div>
</h4>
</div>
</div>
</div>
PS : if you have a solution to retrieve n:n relationship entities without a fetchXml query I am all ears.
I don't think your FetchXML is correct. If you use Advanced Find to create the FetchXML its pretty straight forward. Here is an example for account to lead, note the additional link entity across the many to many intersect table.
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true">
<entity name="account">
<attribute name="name" />
<link-entity name="accountleads" from="leadid" to="accountid" visible="false" intersect="true">
<link-entity name="lead" from="leadid" to="accountid" alias="ac">
<filter type="and">
<condition attribute="leadid" operator="eq" uiname="Test Lead" uitype="lead" value="{FC271420-B2BB-4A87-B852-1DF7CF4B4F3E}" />
</filter>
</link-entity>
</link-entity>
</entity>
</fetch>
I think that the XML is off, try making the wanted filter in an advanced search and download the FetchXML
Hope it helps
M.Acosta.D
Related
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?
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>
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.
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)
I'm trying to make only the available product variants visible in drop downs for products like this one. For example, say you choose 2012 in the first drop down, it would only show the available choices in the second. If you then chose Wed 25th July in the second, it would only show the available variants in the third. At the minute it shows all choices and states 'We don't offer the product in this combination' for an unavailable choice.
So far, my product.liquid page has this code:
<div class="col-7 product-description clearfix">
<h1>{{ product.title }}</h1>
{{ product.description }}
{% include 'addthis' %}
<br/><br/>
{% if product.available %}
{% if product.variants.size > 1 %}
<!-- If the product only has MULTIPLE OPTIONS -->
<form action="/cart/add" method="post" class="product-variants">
<div id="options">
<select id="product-select" name='id'>
{% for variant in product.variants %}
<option value="{{ variant.id }}">{{ variant.title }}</option>
{% endfor %}
</select>
<div class="select-wrapper">
<label for="region">DVD Region</label>
<select id="color" required>
<option value="NTSC">NTSC</option>
<option value="PAL/SECAM" selected="selected">PAL/SECAM</option>
</select>
</div>
<p>Click Here find out more about your region.</p>
</div> <!-- options -->
<div class="price-field"></div>
<input type="submit" name="add" value="Add to cart" id="purchase" />
</form>
{% else %}
<!-- If the product only has ONE variant -->
<form action="/cart/add" method="post" class="product-variants">
<div class="price-field"> {{ product.price | money }}</div>
<input type="submit" name="add" value="Add to cart" id="purchase" />
<input type="hidden" id="{{ variant.id }}" name="id" value="{{ product.variants[0].id }}" /> <!-- passes variant id -->
</form>
{% endif %}
{% else %}
<p>This product is not available</p>
{% endif %}
</div><!-- .col-7 -->
<div class="col-5 last product-thumbs">
<ul>
{% for image in product.images %}
{% if forloop.first %}
<li class="featured-image" >
<a class="zoom " href="{{ image | product_img_url: 'large' }}" title="{{ product.featured_image.alt | escape }}">
<img src="{{ image | product_img_url: 'large' }}" alt="{{ product.featured_image.alt | escape }}" />
</a>
</li>
{% else %}
<li>
<a class="zoom" href="{{ image | product_img_url: 'large' }}" title="{{ image.alt | esacpe }}">
<img class="" src="{{ image | product_img_url: 'small' }}" alt="{{ image.alt | escape }}" />
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div><!-- .col-5 -->
<script type="text/javascript">
// <![CDATA[
var selectCallback = function(variant, selector) {
if (variant && variant.available == true) {
// selected a valid variant
jQuery('#purchase').removeClass('disabled').removeAttr('disabled'); // remove unavailable class from add-to-cart button, and re-enable button
jQuery('#purchase').fadeIn();
jQuery('.price-field').html(Shopify.formatMoney(variant.price, "{{shop.money_with_currency_format}}")); // update price field
} else {
// variant doesn't exist
jQuery('#purchase').addClass('disabled').attr('disabled', 'disabled'); // set add-to-cart button to unavailable class and disable button
jQuery('#purchase').fadeOut();
var message = variant ? "Sold Out" : "We don't offer the product in this combination";
jQuery('.price-field').text(message); // update price-field message
}
};
// initialize multi selector for product
jQuery(document).ready(function() {
new Shopify.OptionSelectors("product-select", { product: {{ product | json }}, onVariantSelected: selectCallback });
{% assign found_one_in_stock = false %}
{% for variant in product.variants %}
{% if variant.available and found_one_in_stock == false %}
{% assign found_one_in_stock = true %}
{% for option in product.options %}
jQuery('.single-option-selector:eq(' + {{ forloop.index0 }} + ')').val({{ variant.options[forloop.index0] | json }}).trigger('change');
{% endfor %}
{% endif %}
{% endfor %}
$('#options div').addClass("selector-wrapper");
{% if product.options.size == 1 %}
$(".selector-wrapper").append("<label>{{ product.options.first }}</label>");
{% endif %}
});
// ]]>
</script>
Any help?