flowblock is shown in Admin view but not contentpage - lektor

I'm not completely new to Lektor but its a few years ago that I worked with it the last time. Now I have the problem that the flowblock is shown in the admin view but not in the content view.
speisekarte.html
{% extends "layout.html" %}
{% block title %}{{ this.title }}{% endblock %}
{% block body %}
<nav>
<table class="nav navbar-nav">
<tr>
{% for href, title in [
['/speisekarte', 'Salate'],
['/speisekarte/vorspeise', 'Vorspeise'],
['/speisekarte/suppen', 'Suppen'],
] %}
<td{% if this.is_child_of(href) %} class="active"{% endif
%}>{{ title }}</td>
{% endfor %}
</tr>
</table>
</nav>
<!--<h2>{{ this.title }}</h2>-->
{{ this.body }}
{% for blk in this.demo_flow.blocks %}
<div class="block block-{{ blk._flowblock }}">
{{ blk }}
</div>
{% endfor %}
speisekarte.ini
[model]
name = Speisekarte
label = {{ this.title }}
[fields.title]
label = Title
type = string
[fields.salat]
lable = Salat
type = flow
flow_blocks = Text Block
gericht.html
<div class="text-block text-block-{{ this.class }}">
{{ this.text }}
</div>
gericht.ini
[block]
name = Text Block
button_label = Text
[fields.text]
label = Name
type = markdown
[fields.preis]
label = Preis
type = markdown
[fields.inhalt]
label = Inhalt
type = markdown
[fields.class]
label = Class
type = select
choices = centered
choice_labels = Centered
default = centered

Shouldn't this.demo_flow.blocks be this.salat.blocks?
Also, you can define a template file per block:
templates/blocks/block-text.html:
<div class="block block-text">
{{ this.content }}
</div>
and then, in your main template just use {{ this.salat }} on the flow, which will render all flow blocks separately.

Related

(Shopify / Liquid ) Background Image only displays right image when assigned inline

I created product cards to display on a collection page in shopify where variants are displayed as different poducts. Everything is working well ( its displayed the correct price of each variant / name and everything ) but the variant image that I have to provide through background-image shows the default product image not the variant image. I tried to place the background-image assignement to inline style and than it worked. The problem is that I cannot assign the background image for the :before pseudo class through inline.
<div class="custom-card-product-folder">
<div class="custom-card-product-folder-2"></div>
<h6 class="custom-card-product-product-title" >{{ card_variant.title | escape }}</h6>
<div class="custom-card-product-product-price {% unless card_variant.compare_at_price == blank %}red{% else %}black{% endunless %}"><span class="grey line-through {% unless card_variant.compare_at_price == blank %}margin-right-ten{% endunless %}">{{ card_variant.compare_at_price | money}}</span> {{ card_variant.price | money}}</div>
<div class="custom-card-product-toggle-wrapper">
{% for option in card_product.options_with_values %}
{% if option.name == "Anzahl" %}
{% for value in option.values %}
<div class="custom-card-product-toggle-value {{ value }}" {% for variant in card_product.variants %}{% if variant.title contains value %}variant-title="{{ variant.title }}" variant-price="{{ variant.price | money }}" variant-image="{{ variant.image | img_url }}"{% break %}{% endif %}{% endfor %}>{{ value | escape }}</div>
{% endfor %}
<div class="custom-card-product-toggle-active-value-overlay"></div>
{% endif %}
{% endfor %}
</div>
</div>
<script>console.log({{ card_variant | json }});</script>
<style>
.custom-card-product-folder-2:before {
background-image: url({{ card_variant.featured_image.src | product_img_url: '700x'}}) !important;
}
.custom-card-product-product-image {
background-image: url({{ card_variant.featured_media.preview_image.src | product_img_url: '700x'}});
}
</style>
I don't fully understand the problem of your code. But regarding assigning a before without using inline style, you can do something like this.
...
<div id="variant-card-{{variant.id}}"
...
<style>
{% for variant in card_product.variants %}
#variant-card-{{variant.id}}:before {
background-image: url('{{ variant.featured_image.src | product_img_url: '700x'}}') !important;
}
{% endfor %}
</style>

How to display data from Jekyll data file based on current page variable

The Problem
I have a div on my Jekyll site where I would like to display data that is generated from _data/book-data.yml, for example:
- name: johnson-everything-under
title: Everything Under
author: Daisy Johnson
publisher: Faber & Faber
pub-date: 12/12/2012
- name: johnson-train-dreams
title: Train Dreams
author: Denis Johsnon
publisher: Granta
pub-date: 01/01/2001
I'm trying to find a way to display the data that corresponds to the relevant page (each book entry has a different page), and I thought maybe this would be possible if the name key corresponds to the page.url, or some other page variable.
What I've tried
On a working page, I have an include which contains the following HTML:
<div class="book-meta">
{% if page.category == "reviews"%}
<div class="book-thumbnail">
<img class="post-thumbnail-lg" src="{{ site.baseurl }}/assets/images/{{ page.thumbnail }}" alt="{{ page.thumbnail }}">
</div>
{% for book in site.data.book-data %}
<div class="book-details">
<ul class="book-meta-list">
<li class="book-meta-item"><p>{{ book.author }}</p></li>
<li class="book-meta-item"><p><em>{{ book.title }}</em></p></li>
<li class="book-meta-item"><p>{{ book.publisher }}</p></li>
<li class="book-meta-item"><p>{{ book.pub-date }}</p></li>
</ul>
</div>
{% endfor %}
{% endif %}
</div>
The CSS is not important, but as it is currently the output of the above HTML is:
Desired output
As you can see, the output contains both the blocks of metadata from the .yml file. I would like to find a way so that only the relevant block of data (the first block in this instance) is displayed:
Potential solution(s)
I thought that there might be a way of matching a page.variable to the YAML block name so only the right book data gets output. Something along the lines of:
{% assign url_substring = page.url | split, '/' | last %}
// url_substring = johnson-everything-under
{% for book in site.data.book-data %}
{% if url_substring == book.name %}
// = true
<p>{{ book.title }}<p>
{% endif %}
{% endfor %}
Other than the fact that I can't get this to work properly, I can also see that the liquid tag {{ book.title }} has no way of knowing which book title to output, even if the page.url matches.
I'm not sure if I'm on the right track here, so if anyone has any other suggestions on how this might be achievable, I'd love to hear it. Thanks in advance.
You can use Jekyll's where filter coupled with a smart include:
{% assign book = site.data.book-data | where: 'title', include.title | first %}
<div class="book-meta">
<div class="book-thumbnail">
<img
class="post-thumbnail-lg"
src="{{ book.thumbnail | prepend: 'assets/images/' | relative_url }}"
alt="{{ book.title }}"
/>
</div>
<div class="book-details">
<ul class="book-meta-list">
<li class="book-meta-item"><p>{{ book.author }}</p></li>
<li class="book-meta-item"><p><em>{{ book.title }}</em></p></li>
<li class="book-meta-item"><p>{{ book.publisher }}</p></li>
<li class="book-meta-item"><p>{{ book.pub-date }}</p></li>
</ul>
</div>
</div>
Note that I also included thumbnail info in the data file..
Then just pass the title parameter to the include (in the layout for your book's page):
{% include books.html title = 'Everything Under' %}
If you'd like to render a "listing", then just loop through and render:
{% for book in site.data.book-data %}
{% include books.html title = book.title %}
{% endfor %}

Django - ajax poll with results on the same page

I'm learning django and I need help with my app.
In a page I have a poll: I want that after a user has voted, the poll form disappears and a div #ajaxresults appears with the updated votes for each option.
I'm using an ajax call but I can't return the updated votes.
If I call directly '/polls/4/results' I can see the right list but I can't include that block on the same page of the form.
What am I missing?
urls.py
app_name = 'polls'
urlpatterns = [
path('', views.index, name='list'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]
view.py
def results(request, question_id):
question = get_object_or_404(Question, pk=question_id)
#return render(request, 'polls/results.html', {'question': question})
return redirect(question.get_absolute_url())
#require_POST
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
selected_choice = question.choice_set.get(pk=request.POST['selectionId'])
selected_choice.votes += 1
selected_choice.save()
return redirect('polls:results', question_id = question_id)
detail template (extends base.html)
<form id="quiz-module" action="#">
<input type="hidden" id="pollId" name="pollId" value="{{question.id}}">
{% csrf_token %}
<fieldset>
<h2>{{ question.question_text }}</h2>
<ul>
{% for choice in question.choice_set.all %}
<li><input type="radio" name="opt" value="{{ choice.id }}" {% if forloop.first %}required {%endif%}/>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
</fieldset>
</form>
<section id="quiz-results">
<h3>Your vote</h3>
<p id="ajaxresults"></p>
<h3>All votes</h3>
<dl>
{%block updated_results %}{% endblock %}
</dl>
</section>
template vote is empty
template results (extends nothing)
{%block updated_results %}
{% for choice in question.choice_set.all %}
<dt>{{ choice.choice_text }}: </dt><dd id="choiceId-{{ choice.id }}">{{ choice.votes }}</dd>
{% endfor %}
{% endblock %}
js
var args = {
type:"POST",
url:"/polls/"+pollId+"/vote/",
data:data,
success: function( data ) {
//print your vote
results.children('#ajaxresults').html(selectionText);
form.hide('fast');
results.show('fast');
},
error: function(xhr, status, error) {
alert(error+'<br/>'+"Sorry. Can't submit your vote. Please, reload the page and try again")
},
};
$.ajax(args);

Content types of my images doesn't display

Why is it the images will not display if I'm going to loop them like this?
{% for item in content.field_room_gallery_pictures['#items'].getValue() %}
<div class="col-xs-6 col-md-4 image-item">
{{item.value}}
</div>
{% endfor %}
And when I fetched the data if there is or not using kint.. it will display an array with the value of 3 using this code..So it means in my field_room_gallery_pictures there is an array of data.
{{kint(content.field_room_gallery_pictures['#items'].getValue())}}
have your tried this:
{% for i in 0..content.field_room_gallery_pictures|length %}
{%if content.field_room_gallery_pictures[i]['#item'].entity.uri.value != "" and content.field_room_gallery_pictures[i]['#item'].entity.uri.value is not empty %}
<div>
{{ content.field_room_gallery_pictures[i]}}
</div>
{%endif%}
{%endfor%}
works fine for me.

Adding an object to a dropdown list without reloading the page

Hi I have a 'member' model that references a 'role' model. What I would like is when a user creates a 'member' they can either choose from a list of default 'roles' (that have been loaded to the database when the server starts using fixtures) or they can click on add role and then type in and click submit and the newly created role is created and assigned to the newly created 'member' object.
I would like it so that I am able to just create a role without submitting, and the role then appears in the dropdown menu for the role field in the member model. Is this where I would need to learn about AJAX to implement this feature?
Models
class MemberRole(models.Model,get_fields):
name = models.CharField(max_length = 20)
def __unicode__(self):
return self.name
class Member(models.Model,get_fields):
first_name = models.CharField(max_length = 20)
role = models.ForeignKey(MemberRole, null = True, blank = True)
View
def add_member(request):
model_url = 'member-add'
if request.method == "POST":
rform = MemberRoleForm(request.POST, instance=MemberRole())
mform = MemberForm(request.POST, instance=Member())
if rform.is_valid() and mform.is_valid():
new_role = rform.save()
new_member = mform.save(commit=False)
new_member.role = new_role
new_member.save()
return HttpResponseRedirect('members')
else:
rform = MemberRoleForm(instance=MemberRole())
mform = MemberForm(instance=Member())
return render_to_response('create_model.html', {'role_form': rform, 'member_form': mform, 'model_url': model_url,},context_instance=RequestContext(request))
snippet create_model.html
<div id = "subtemplate">
<form action="{% url model_url %}" method="POST">
{% csrf_token %}
{% if model_url == 'member-add' %}
{% for field in member_form %}
{% if field.label == 'Role' %}
<div id="roleExistsMemberForm">
<button type="button" onclick="showDiv()">Add Role</button>
{{ field.errors }}
{{ field.label_tag }} {{ field }} {{ field.help_text }}
</div>
{% else %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
</div>
{% endif %}
{% endfor %}
<div Id="addRoleOnMemberForm">
{% for field in role_form %}
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% endfor %}
</div>
{% else %}
<ul>
<li>{{ form.as_ul }}</li>
</ul>
{% endif %}
<div id="centerbuttons">
<input id="save_contact" type="submit" value="Add"/>
</div>
</form>
Yes, Ajax would be the first point of call for something like this. You can submit the form in the background to a Django view, the view could then respond with a fresh list of options to re-populate the drop down list with.

Resources