Conditional for development environment in Bigcommerce's Handlebars - handlebars.js

Working from the Cornerstone theme in Stencil, I want to be able to do different things depending on whether I am on my local NPM environment or the production site.
Looking at the current URL is not enough as the page has to be already loaded for that. I want to have conditionals in the template, with handlebars, when the markup is being generated. Something like:
{{#if developEnvironment '===' 'true'}}
<p>I'm local</p>
{{else}}
<p>I'm remote</p>
{{/if}}
I see nothing useful in the theme_settings vars.
Any ideas?

BigCommerce provides an actual key/value pair for determining if in development or not within the context.
I'm using stencil CLI v2.1.0, so it might not be the case for older versions.
{{#if in_development}}
In Development
{{else}}
In Production
{{/if}}

You can try using this conditional statement:
{{#if settings.maintenance.secure_path '==' 'http://localhost:undefined'}}
You are running on development.
{{else}}
You are running on production.
{{/if}}

You could add your own custom theme_settings values.
First, navigate to the ./config.json file. Look for the variations array in this file.
It should look something like this:
"variations": [
{
"name": "Light",
"id": "light",
"meta": {...},
"images": {...},
"settings": {
"developEnvironment": true,
...
Under the settings object you can add your own custom theme_settings values just like I did above: "developEnvironment": true,. Now in your theme file you can do something like this:
{{#if theme_settings.developEnvironment}}
<!-- Do something -->
{{/if}}

Related

How to use parameter in assemble partial

How to use parameter in handlebar partial I am using grunt-assemble and cant find anything in docs
For Example I will create a partial name heading and use it in my template
<h1 class="tac mt-80 underline">
{{heading}}
</h1>
<body>
{{> heading "Test"}}
</body>
unfortunately, thats not possible with grunt-assemble out of the box.
Their recommended way is to use the parseJSON helper for that:
{{#parseJSON '{"heading": "TEST"}'}}
{{> heading }}
{{/parseJSON}}
But you should take a look at the current implementation of assemble, which includes a updated version of Handlebars (which provides your wished functionality). It seems like they moved away from Grunt in favor of compatibility with Gulp.

How to create recursive hbs code in ember?

I have a hbs file that contains following
//some ohter code
-------------------------------------
{{#each items}}
<li>
{{name}}
{{#if items}}
<ul>
//partial should go here
</ul>
{{/if}}
</li>
{{/each}}
---------------------------------------------------
And I want to use same section recursively replacing //partial should go here. How can I do that? Appreciate any help
Ember used to have parital, render and include template tags, which they are trying to get rid of however.
Now, probably the best way is to make use of components. If you are on ember-cli, just open your terminal and type ember g component my-include. It generates a *.js and a *.hbs file (naming depending on whether you are using pods or not).
Then you put the template code you want to use multiple times in the newly created *.hbs file, and then in your existing template code:
{{#if items}}
<ul>
{{my-include}}
</ul>
{{/if}}
You might want to take a look at: https://guides.emberjs.com/v2.9.0/components/defining-a-component/ for more information
You can also look at this sample working twiddle.

Change some html in layout template when on a certain route (with iron-router and meteor.js)

I have a template I have set up as my layout using iron-router:
Router.configure({
layoutTemplate: 'main'
});
Within this layout, I have a line of html that I would like to be changed on certain routes.
My ideas is doing something like:
{{#if landing }}
<div id="page-wrapper">
{{/if}}
However, how do I implement this for a certain route? I want this variable to be true on every route except for 1.
I think that this kind of "change the template based upon what route I'm on" logic fits best into the use of a template for that route (and any others that will make this same change. Depending on the change required, you may be able to call in your base Template into the modified template.
Example:
Router.route('/yourSpecialRoute', function(){
this.layout('OtherLayout');
});
See the Layout docs - I borrowed the syntax of Setting Region Data Contexts
Having said, if you prefer not to switch layouts per route, consider setting a data on your route (something like {data: item} as shown here in the iron:route readme which can then be read by a global helper (Template.registerHelper syntax) - this will at least make it consistent across your routes / templates.

Meteor's iron:router isn't doing {{renderRouter}} as expected or documented

I've got a very simple template problem going on that appears to be similar to this guy's problem, though I've tried to build a simple example to demonstrate the problem and hopefully have someone explain to me how to fix or work around it.
Although as I'm doing some online research, it may be that the official documentation is out of date with the code. The reason I haven't bought into accepting that just yet is that the problem seems to have existed for a while, the dates on such articles in forums appears to be fairly old, and there's talk of it being fixed. There's also talk the feature is gone. What's the new way, if there is one?
I'm using Meteor 0.9.0.1 with iron:router 0.9.1. Specifically, I set up my project like this:
$ meteor create ironTest
$ cd ironTest
$ meteor add iron:router
$ meteor
Pointing my browser at http://localhost:3000/ as instructed, shows the default project. So far so good.
Now make ironTest.html contain this:
<body>
<h1>Before</h1>
{{renderRouter}}
<h2>Afterward</h2>
</body>
<template name="hello">
Hello Template
</template>
<template name="goodbye">
Goodbye Template
</template>
Make ironTest.js contain this:
Router.configure({
autoRender: true // we will experiment with this Boolean shortly
});
Router.map(function () {
this.route('hello');
this.route('goodbye');
});
If you go to the routes http://localhost:3000/hello and http://localhost:3000/goodbye, you'll see the templates correctly render as expected and documented, appended to the <body> element, so it appears after the <h2> element.
According to the current documentation for iron:router, one should be able to set the autoRender property to false, and the template should no longer be appended to the <body> element, but rather be injected where the Handlebars (okay, Spacebars) element {{renderRouter}} is, that is, between the <h1> and <h2> elements.
When I try this, visually it doesn't do anything. Opening a JavaScript Console to look at errors shows none. Although, by deliberately going to an invalid route it will show a missing template router exception, showing the routing code is indeed working.
Does anyone know how to coerce the code above into working?
For the curious, I've got a working simplistic equivalent that might be of use to others working this problem.
This new ironTest.html uses a template (for a layout) with no <body>:
<template name="main">
<h1>Before</h1>
{{> yield}}
<h2>Afterward</h2>
</template>
<template name="hello">
Hello Template
</template>
<template name="goodbye">
Goodbye Template
</template>
This ironTest.js instead uses a layout:
Router.configure({
layoutTemplate : 'main'
});
Router.map(function () {
this.route('hello');
this.route('goodbye');
});
It's worth an aside that this solution doesn't work for me, as I don't want a global layout, and have concern that riddling layouts in the route themselves is a tighter coupling than desired for my purposes.
I'm currently looking for a way to dump debugging log information from the Router as it performs transitions, but that's another story.

Getting "pages" from different collection with Assemble

Let's say I have a page from a collection where I want to list every yaml tag from a different pages collection.
If they were in the same collection this would do the trick:
<section class="see-also">
<header>Related Contents:</header>
{{#each tags}}
<p>In <span class="tag">{{tag}}</span>:</p>
{{#each pages}}
<li>{{data.title}}</li>
{{/each}}
{{/each}}
</section>
But since im trying to access this collection from a page on a different one, how could this be achieved?
I would recommend creating a custom helper for this. Since there is no easy way to write a helper that will work the way you're describing for your specific setup, here is a great example of how a custom helper was used to solve a similar problem: https://github.com/assemble/assemble/issues/254
If I had this use case I would probably put the 'pages' yaml in a separate yml file instead of embedded on the page.
If in your gruntfile you include a path to data files:
assemble: {
options: {
data: ['<%= site.data %>', 'data/*.yml']
}
}
And your file structure includes:
── data
│ └── page1.yml
│ └── page2.yml
You can access {{#each page1.pages}} from anywhere.
Or you could have a shared.yml file that includes information like the pages collection referred to, and the rest of the data stays on each page.
Further resources:
http://assemble.io/docs/Data.html
http://assemble.io/docs/YAML-front-matter.html

Resources