I'm having troubles using front matter in my layouts. It simply displays out the front matter to the page without creating the data needed for my layout.
Here goes the code:
/src/_includes/layouts/base.html
---
rightLinks : [
{
"icon": "mail_outline",
"href": "https://google.com"
}
]
---
<!DOCTYPE html>
<html lang="es-AR">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons"
rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:ital,wght#0,300;0,400;0,600;0,700;0,900;1,300;1,400;1,600;1,700;1,900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/global.css">
</head>
<body>
<!-- top-nav try to use rightLinks data from this layout -->
{% include "partials/top-nav.html" %}
{% include "partials/main-nav.html" %}
<main tabindex="-1" id="main-content">{% block content %}{% endblock %}</main>
</body>
</html>
/src/_includes/layouts/home.html
{% extends "layouts/base.html" %}
{% block content %}
<section class="hero is-black is-fullheight-with-navbar hero-home">
<div class="hero-body">
<div class="container">
<div>
<h1 class="title text-black text-huge">
Nexus Materiales Eléctricos
</h1>
<h2 class="subtitle is-4">
Somos mayoristas en insúmos eléctricos de calidad.
</h2>
</div>
<div class="mt-6">
<a href="/marcas" class="button is-rounded is-large is-dark is-uppercase text-semi-black">
ver marcas
</a>
</div>
</div>
</div>
</section>
<section class="section has-background-white">
<h2 class="title">Nuestras marcas destacadas</h2>
<h3 class="subtitle">Calidad y seguridad</h3>
</section>
{% endblock %}
/src/index.md
---
title: 'Hello World!'
layout: 'layouts/home'
---
I get as a visual result the actual string at the top:
It seems to me that Eleventy, for some reason, is skipping the front matter.
Here is my Eleventy configuration file:
module.exports = function(config) {
config.addWatchTarget("./src/sass/");
config.addPassthroughCopy('./src/images')
// Return your Object options:
return {
dir: {
input: "src",
output: "dist"
},
markdownTemplateEngine: 'njk',
dataTemplateEngine: 'njk',
htmlTemplateEngine: 'njk',
}
};
Someone can explain to me why is this happening, and how can I solve this? Thanks
Front-matter data is only available in layout files that are directly referenced by pages with the layout: front matter key, not with Nunjucks {% extends %}. Front matter data in directly referenced layout files are merged with other data as part of 11ty's data cascade. (11ty docs: front matter in layouts)
For example:
<!-- index.md -->
---
layout: layouts/content
---
# some content here
{# layouts/base.njk #}
---
hello: "world"
---
{# ^ the above will be printed as plain text and isn't available #}
{# layouts/content.njk #}
---
someKey: "something"
---
{% extends "layouts/base.njk" %}
{{ someKey }}
{# ^ this will render "something" as expected #}
This is likely because {% extends %} is a feature of Nunjucks, and Eleventy is not aware of which other Nunjucks files are being referenced.
For your situation, you have a couple of options. First, you could place your front matter data in layouts/home, since that's what you're referencing in your index.md. Another option is to just use Nunjuck's set tag.
{% set links = [
{
"icon": "mail_outline",
"href": "https://google.com"
}
] %}
{% for link in links %}
{{ link.icon }}
{{ link.href }}
{% endfor %}
Related
I've been using https://stripe.com/docs/payments/checkout/migrating-prices#server-side-code-for-inline-items and https://stripe.com/docs/payments/checkout/accept-a-payment as well as other guides/SO posts as a guide.
The checkout button in payments.html page doesn't work; nothing happens on the page.
In the Flask's /payment function, I have been able to print out the session/session.id fine.
I have tried passing the session and the session.id to the payments.html page, but neither has worked. The {{price}} on payments.html works fine.
What am I overlooking/messing up here to get the Checkout page working?
base.html
<!DOCTYPE html>
<html>
<head>
<title>Stripe Checkout</title>
<link rel="stylesheet" href="{{ url_for('static', filename='main.css') }}">
<link rel="stylesheet" href="{{ url_for('static', filename='bootstrap.min.css') }}">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<meta name="mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
</head>
<body>
<div class="container">
{% block content %}
{% endblock %}
</div>
{% block scripts %}
{% endblock %}
</body>
</html>
Payments.html
{% extends "base.html" %}
{% block content %}
<div>
<h1>Cost</h1>
<h2>Pay ${{price}}</h2>
<button type="button" class="btn btn-primary" id="checkout">Pay with Card</button>
<button type="button" class="btn btn-primary" id="back">Back</button>
</div>
<div id="status">
<br>
<div class="alert alert-primary" id="alert" role="alert"></div>
</div>
{% endblock %}
{% block scripts %}
<script src="https://js.stripe.com/v3"></script>
<script>
var stripe = Stripe('pk_test_...');
var checkoutButton = document.querySelector('#checkout');
checkoutButton.addEventListener('click', function () {
stripe.redirectToCheckout({
sessionId: {{sessionID}}
});
});
</script>
{% endblock %}
Flask's /payment function
#app.route("/payment")
def payment():
price = "50"
session = session.Session().getSession(int(price)*100)
sessionID = session.id
print("SessionID:", sessionID)
return render_template("payment.html", sessionID=sessionID, price=price)
Python Stripe file
import stripe
stripe.api_key = 'sk_test_...'
class Session:
def __init__(self):
pass
def getSession(self, price):
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price_data': {
'currency': 'usd',
'product_data': {
'name': 'blah',
},
'unit_amount': price,
},
'quantity': 1,
}],
mode='payment',
success_url='https://example.com/success',
cancel_url='https://example.com/cancel',
)
return session
Thanks to #floatingLomas, I didn't think to use the browser's console. Yeah, I figured it out, I have to use the session.id and have quotes around {{sessionID}}.
I'm trying to create a form in which the user choices an instance of model object (Invoice) already saved in the database and submits. I've tried to initialize the JS, but have little experience working with JS in html so I'm not totally sure I'm doing it right.
Right now the below code does not render anything besides the submit button in the form. I have tried adding a random input field (worked) and tried unpacking and rendering the "invoices" context as raw text on the same page (also worked) so I think I've narrowed the issue down to it being the form choices.
header.html
<head>
{% load static %}
<!-- Compiled and minified JavaScript -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<!-- Compiled and minified CSS -->
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel = "stylesheet"
href = "https://fonts.googleapis.com/icon?family=Material+Icons">
<script type = "text/javascript"
src = "https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script>
$(document).ready(function(){
$('select').formSelect();
});
</script>
</head>
<body>
<nav>
<div class="nav-wrapper">
Elb
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Invoice Upload</li>
<li>Inventory Upload</li>
</ul>
</div>
</nav>
{% block content %}
{% endblock %}
</body>
form.html
{% extends 'main/header.html' %}
<body>
{% block content %}
<br>
<br>
<form method="POST">
{% csrf_token %}
<label for="invoice">Invoice</label>
<select id="invoice" name="invoice">
<option class=browser-default value="" disabled selected>Choose invoice</option>
{% for invoice in invoices %}
<option class=browser-default value="{{ invoice }}">{{ invoice }}</option>
{% endfor %}
</select>
<br><br>
<input type="submit" value="Save" />
</form>
{% endblock content %}
</body>
views.py
def inventory_upload(request):
if request.user.username == 'admin': # Check that user is authorized
if request.method == 'POST': # Render HTML of results page returned to user
...do something and return to user...
else: # Initial html display to user
invoices = Invoice.objects.all()
inventory = get_inventory_from_sheet()
form = BulkInventoryUpload
return render(request=request,
template_name='form.html',
context={'invoices': invoices, 'inventory': inventory, 'form': form})
else: # Bounce user back to homepage if not authorized
return redirect('main:homepage')
forms.py
from django import forms
from django.forms import formset_factory
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from .models import Invoice
class BulkInventoryUpload(forms.Form):
invoice = forms.CharField(label='invoice', max_length=150)
def get_invoice(self, commit=True):
invoice = self.cleaned_data['invoice']
return invoice
For anyone else running into the same issue (credit to Sean Doherty in comments above for the answer):
JQuery needs to be loaded before CSS (and from my testing it looks like before the JS as well)
The below order got it working for me:
<head>
{% load static %}
<!-- Compiled and minified JavaScript -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<script>
$(document).ready(function(){
$('select').formSelect();
});
</script>
<!-- Compiled and minified CSS -->
<meta name = "viewport" content = "width = device-width, initial-scale = 1">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<link rel = "stylesheet"
href = "https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
While using chartit with django, I got a problem stating " " instead of the real chart.. What may be the possible reasons... Where might I mistaken.. My webserver works well but just chart is not displayed. Thanks in advance....
In views.py
def moisture_graph(request):
ds = DataPool(
series =
[{'options': {
'source':sensor.objects.all()},
'terms':['time_stamp','soil_moisture']
}])
cht = Chart(
datasource = ds,
series_options =
[{'options':{
'type':'line',
'stacking':False},
'terms':{
'time_stamp':['soil_moisture']
}}],
chart_options =
{'title':{'text': 'Soil Moisture Graph'},
'xAxis':{'title':{'text':'Time'}}})
context = {'sensor_chart':cht}
return render(request, 'analysis/plot.html', context)
In plot.html
{% extends "orgs/home.html" %}
{% load staticfiles %}
{% block title %}
<title>AgroTech | Graph Plot</title>
<link rel = "stylesheet" type="text/css" href="{% static 'orgs/css/content_all.css' %}" />
<link rel = "stylesheet" type="text/css" href="{% static 'orgs/css/sidebar.css' %}" />
<! include highchart and jquery library >
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://code.highcharts.com"></script>
{% block about_css %}
<link rel = "stylesheet" type="text/css" href="{% static 'analysis/css/plot.css' %}" />
{% endblock %}
{% endblock %}
{% block sidebar %}
<ul class = 'sidebar_list'>
<li id = 'list_category'>
Plot Categories...
</li>
<li>
Soil Moisture Graph
</li>
<li>
Temperature Graph
</li>
<li>
Humidity Graph
</li>
</ul>
{% endblock %}
{% block page_content %}
<div id="content_heading">
{% block plot_heading %}
Soil Moisture Data Plot
{% endblock %}
</div>
<div id='graph'>
{% load chartit %}
{{ sensor_chart }}
{{ load_charts }}
</div>
{% endblock %}
my issue when I search on my site using jquery it is only searching on the page that is displayed at the moment and I would like it to search all of my data and then display on the page accordingly, which is about 2.6 M entries. I am using the core django paginator for my pagination and using simple jquery and ajax for my search tool. Please help!
heres my view:
def tissues(request):
contact_list = TissueTable.objects.all()
paginator = Paginator(contact_list, 100) # Show 25 contacts per page
page = request.GET.get('page')
try:
contacts = paginator.page(page)
except PageNotAnInteger:
# If page is not an integer, deliver first page.
contacts = paginator.page(1)
except EmptyPage:
# If page is out of range (e.g. 9999), deliver last page of results.
contacts = paginator.page(paginator.num_pages)
return render(request, '.html', {'contacts': contacts})
heres my two templates, base and home,
base.html:
<html>
<head>
<title>Animal NGS DATA</font></title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css">
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$('a[rel="external"]').attr('target', '_blank');
</script>
<style>
th
{
border-bottom: 1px solid #d6d6d6;
}
tr:nth-child(even)
{
background:#e9e9e9;
}
</style>
</head>
<body>
<div data-role="page" id="pageone">
<div data-role="header">
<h1 left>NGS CUFFLINK'S DATA</h1>
</div>
<div data-role="main" class="ui-content">
<form>
<input id="filterTable-input" data-type="search" placeholder="Search Tissue Data...">
</form>
<table data-role="table" data-mode="columntoggle" class="ui-responsive ui-shadow" id="myTable" data-filter="true" data-input="#filterTable-input">
</head>
<body>
<map title="Navigation Bar">
<P>
NGS Data
Genes
Experiment
Organisms
Tissue Data
</P>
</map>
<h1><font color='red'>Tissue Data</font></h1>
{% block content %}
{% endblock %}
</body>
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'myapp/style.css' %}" />
</html>
and my home.html
{% extends "tissues/base.html" %}
{% block content %}
<!--<table id='table' data-mode="columntoggle" border = '10' bordercolor = 'mahogany'>-->
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
<table data-role="table" id="myTable" class="ui-responsive ui-shadow" data-filter="true" data-input="#filterTable-input" bgcolor = 'cyan'>
<thead>
<tr bgcolor = 'pink'>
<th>Tissue ID</th>
<th>Tissue Term</th>
<th>Definition</th>
</tr>
<thead>
<tbody>
{% for b in contacts.object_list%}
<tr>
<td>{{b.tissue_id}}</td>
<td>{{b.tissue_term}}</td>
<td>{{b.definition}}</td>
</tr>
{% endfor %}
</table>
<div class="pagination">
<span class="step-links">
{% if contacts.has_previous %}
previous
{% endif %}
<span class="current">
Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
</span>
{% if contacts.has_next %}
next
{% endif %}
</span>
</div>
{% endblock %}
Looks like you need separate view function, and deliver it results separately via ajax. May be something like this one:
def ajax_activity_objects_search(request):
search_phrase = request.GET.get('q')
matched = ActivityObject.objects.filter(
address__icontains=search_phrase,
)
response = ''
for act_object in matched:
response += '<option value="' + str(act_object.id) + '">' \
+ act_object.address + '</option>'
return HttpResponse(response)
I'm just curious about this issue I have:
In the MainController I have this:
$scope._layout = { currentYear: moment().format('YYYY') };
While in the html layout page I have this.
[...]
<body class="" ng-controller="MainController">
<!-- BEGIN PAGE CONTAINER-->
{% block content %}{% endblock %}
<!-- END CONTAINER -->
<span>{{_layout.currentYear}}</span>
[...]
This above won't work, {{_layout.currentYear}} displays nothing, but if I change it to be ng-bind, then it works.
[...]
<body class="" ng-controller="MainController">
<!-- BEGIN PAGE CONTAINER-->
{% block content %}{% endblock %}
<!-- END CONTAINER -->
<span ng-bind="_layout.currentYear"></span>
[...]
Why the {{_layout.currentYear}} syntax doesn't work?