Chaning CSS for Home Page Only | Shopify - frontend

I'm using Shopify to build out my website and I like the home page nav how it is, but I'd like to change the other pages nav bar to 100% width. Since they all share the same code I know I'll have to build out an if statement, I'm just not familiar enough with Shopify to build it out.
{%if page.handle == "Home page"%}
.page-width {
margin: 0 auto;
padding-left: 15px;
padding-right: 15px;
}
{% endif %}
Here is the code I was working with that doesn't work. I was just seeing if I could get the if statement to work but I could not.

On the index page, you don't have a "page" object.
You can try with this:
{% if template.name == "index" %}
.page-width {
margin: 0 auto;
padding-left: 15px;
padding-right: 15px;
}
{% endif %}
Which uses the template name to check if it's the index page (Home Page).
Or this:
{% if request.path == "/" %}
.page-width {
margin: 0 auto;
padding-left: 15px;
padding-right: 15px;
}
{% endif%}
Which uses the path of the URL to check if it's the index page.

Asset files do not know what page you're on
The files in your assets folder are intended to be static resources that can be strongly cached by the server and the browser. This means that every time a resource in the assets folder is requested, the exact same file will be returned by the server.
This means that asset files do not know about any of the dynamic information on your website - including what page the viewer is on, what product they're viewing, the contents of the cart, etc. The only Liquid variables that you should be accessing in your asset files are the theme's settings variables and translations.
There are many ways that you could rearrange your code or site structure to accommodate for this, though. Some ideas include:
If you have a lot of rules that apply to a specific page, make an asset file for those rules and in your theme files wrap that file's inclusion with the conditional check.
Example:
{% if template.name == 'index' %}
{{ 'index-styles.css' | asset_url | stylesheet_tag }}
{% endif %}
Add the {{ template.name }} and/or {{ template.suffix }} as class names or data attributes to the <body> tag or some other high-level tag. You can then scope your selectors for specific pages quite easily.
Example:
HTML:
<body class="template-{{ template.name }}">`
CSS:
.template-index .page-width {

Related

Rendering a component inside another in Nunjucks & Fractal

I'm working on a design system and just getting my head around the component way of thinking.
We're using Nunjucks and Fractal.
We have an existing component, an accordion which gets it's data from a JSON object. The props being title and content.
I've built a component, like a table of contents, which displays a list of styled links, using a simple loop, pulling in from a ToC.config.js file.
I need to include that new component within the accordion component, the ToC has a title and an array containing urls and text for each link.
At present I've just copied the HTML from the accordion's view in Fractal, but that's probably not the way to go, but visually it's as the designer requires.
I can also render the accordion correctly if I put all the links, HTML and all in the config, as a string, but that's not the way it should work either.
What I want to do, which is probably the proper way, is pull that accordion in and populate it with my ToC component.
{% render '#my-accordion', 'accordion: items' %} doesn't do what I want and I can't seem to figure out how to achieve what I need to do.
Something like so:
{% render '#my-accordion' %}
// Pass in data from ToC, somehow
{{ title: title }}
{% for item in items %}
{{ item.text etc }}
{% endfor %}
Then I would have my accordion component, where its title, links and HTML etc are those from my ToC component. Sorry for the rough pseudo above, it's more an example of what I want to do. I can't copy code to an external resource.
using render doesn't appear to be the way to go, unless I'm missing something? I can't pass the list through as a string as it has classes and aria for the current page etc and content authors will be building pages with these.
A little nudge in the right direction would be great.
You can add a render-filter that similar to include and macro.
import 'nunjucks.min.js';
var env = new nunjucks.Environment({autoescape: true});
env.addFilter('render', function (template, ctx) {
const html = env.render(template, ctx); // try-catch
return env.filters.safe(html);
});
Usage
// table.njk
<table>
{% for e in rows %}
{% 'row.njk' | render({row: e}) %}
{% endfor %}
</table>
// row.njk
<tr>
{% for c in row.cols %}
<td> {{ c.name }} </td>
{% endfor %}
</tr>

how to check ping response of multiple website in django based site?

I have created one website which contains different company application in bootstrap cart format. This cart is showing the application version and allowing the user to download it by clicking on the button.
Requirement:
Now I am trying to implement functionally where it will show whether the site is online/reachable or not by a green color dot. I have tried the below code but I found that only for a few 1 sites it is showing green color and for the remaining, it is showing False.
Also found that the site is taking time to load the home page I have seen this functionality implemented in a few websites. Can anyone suggest to me how to implement it in the best way?
Please find the below code.
views.py(showing only logic code)
data = {}
for singlesite in allsites:
site=singlesite.product_by
try:
subprocess.check_call(['ping', '-c', '1', str(site)])
except subprocess.CalledProcessError:
online = False
data['online'] = online
print('Checking The Ping Response:', online)
else:
online = True
data['online'] = online
print('Checking The Ping Response:', online)
in the above code, product_by means I am taking it from model form.
HTML code.
.logged-in {
color: green;
font-size: 8px;
}
.logged-out {
color: red;
font-size: 8px;
}
{% if online %}
<span class="logged-in">●</span>
{% else %}
<span class="logged-out">●</span>
{% endif %}
Any help on this how to handle delay and implement this functionality will be appreciated. Thank you.

CSS selector for ionic-radio labels

I'm creating a list of radio buttons which when checked should change the color of corresponding label but it seems not to work at all using css selectors.
what am i missing here?
template-
<ion-list class="addressList">
<ion-radio-group">
<ion-item *ngFor="let address of address">
<label for="ok" >
{{address.address}}
</label>
<ion-radio id="ok" class="radio-custom" mode='ios' slot="end" value="{{address.address}}"></ion-radio>
</ion-item>
</ion-radio-group>
</ion-list>
app.scss -
:checked + label {
color: var(--ion-color-primary) !important;
}
I think the best way to figure out styling is to use chrome dev tools, click on the item in question and see what classes such element obtains during "checked" state:
Then you could build your styling rules around it, but please note that if the element is inside of a "shadow root" you need to use css variables to apply styles (since those elements' style would be incapsulated inside shadow dom)
<ion-list class="addressList">
<ion-radio-group>
<ion-item *ngFor="let address of [0,1,2,3,4,5,6,7]">
<ion-label>address #{{ address }}</ion-label>
<ion-radio mode='ios' slot="end" value="{{address}}"></ion-radio>
</ion-item>
</ion-radio-group>
</ion-list>
and css:
.item-radio-checked {
color: red;
}
You can play with many CSS vars Ionic team created from here: https://ionicframework.com/docs/api/item#css-custom-properties
These are applied at ion-item scope.

Using an ACF gallery with Timber/Twig

I'm using Timber (the WordPress plugin implementation of Twig) and the Advanced Custom Fields plugin gallery field. I have a working gallery under a custom post type, so ACF and Timber are working elswhere in the site, but not for a standard page. When I try to add a gallery to a page, all I end up with is empty markup for the img src tag.
I have this in page.php in the template folder:
$context = Timber::get_context();
$page = new TimberPost();
$context['page'] = $page;
if ($photos = $page->get_field('photos')) {
$context['photos'] = $photos;
}
I have this in default.twig in the templates/page/ folder in the theme (html removed for simplicity):
{% if page.photos %}
{% for p in page.photos %}
<img src="{{ p.sizes.gallery|relative }}" alt="{{ p.alt }}" />
{{ p.caption }}
{% endfor %}
{% endif %}
This results in the page source <img src="" alt="">.
If I use {{ dump(photos) }} inside the for p in page.photos statement, it dumps the array of images I have entered in the Gallery field on the backend. So the image array exists and it being output. The relative extension runs for all post types; removing it makes no difference here.
So why is the p.sizes.gallery|relative function not outputting each image's url and caption?
You append the data to the $context['photos'] so I believe you should change your code to check for if photos and iterate as for p in photos

Twig direct include doesn't work, only "with"ing specific keys does

I'm using Pattern Lab with twig templates and having an issue with using objects directly in the with statement in includes.
This is my teaser-content-blocks organism:
{% set content_blocks = [
{
teaser_photo: {
url: 'https://img.buzzfeed.com/buzzfeed-static/static/enhanced/terminal01/2011/3/29/17/enhanced-buzz-14894-1301433714-5.jpg',
alt: 'Man sleeping on a cake',
title: 'Man sleeping on a cake',
height: '200px',
width: '400px',
},
}
] %}
<div class="teaser-content-blocks">
{% for content_block in content_blocks %}
{% include '#molecules/teaser-content-block.twig' with content_block only %}
{% endfor %}
</div>
This is the teaser-photo atom:
<div class="teaser-photo">
<img
src="{{ url }}"
alt="{{ alt }}"
title="{{ title }}"
/>
</div>
And this is what I'm attempting to do with the teaser-content-block molecule:
<div class="teaser-content-block">
<div class="left">
{% include '#atoms/teaser-photo.twig' with teaser_photo only %}
</div>
<div class="right">
{% include '#atoms/title.twig' with { title: 'Sleep on a cake', element: 'h3' } only %}
{% include '#atoms/teaser-body.twig' with { body: "When we say 'sweet dreams', this isn't quite what we mean! Check this mad lad not understanding the general concept of pillows! This utter banterboy has completely confused what he is meant to use as a confectionary-based celebration of one's birth and a soft item of bedding designed to cushion the head during sleep or light rest. Mental!" } only %}
</div>
</div>
It seems, however, that the with teaser_photo only statement causes twig to break and not compile, with an error of Catchable fatal error: Argument 1 passed to Twig_Template::display() must be of the type array, null given.
If I change that include statement to the following:
{% include '#atoms/teaser-photo.twig' with { url: teaser_photo.url, alt: teaser_photo.alt, title: teaser_photo.title } only %}
... it works fine, but this is way too verbose for my liking. I'd rather just pass the object down as it is. It just seems to not want to pick it up in the correct manner, even though theoretically it should work the same.
I'm not a twig expert so I may be missing something really obvious.
Any help much appreciated as always!
Discovered the issue. Pattern Lab of course tries to render every available pattern, so it was trying to render teaser-content-block.twig which is trying to reference the variable teaser_photo, which of course doesn't exist in this scope. So the cure was to replace that line with one that uses a default, like so:
{% include '#atoms/teaser-photo.twig' with teaser_photo|default({}) only %}
... or at least something that does a similar thing. Thanks to #DarkBee too for taking the time to have a look.

Resources