The problem is fairly complex. Let's say the input of my function is a string. The input can contain the following keywords:
"{% if some_condition %}" (Start)
"{% endif %}" (End)
"{% else if some_other_condition %}" (Optional)
"{% else %}" (Optional)
Along with these keywords, the input may also contain any other string. The conditions are basically just names of variables, so within a string before parsing, they are just strings (any valid string is acceptable as a variable name).
Here's what the function is meant to do:
Take the input and look for start and end tag pairs.
When found, look inside the contents between the start tag and end tag.
If the content contains "{% else if <any_condition> %}" OR "{% else %}", then do nothing.
Otherwise, add the "{% else %}<div class='empty'>Empty</div>" string right at the end of the content.
So for clarity, here is an example input:
{% if username %}
<p>Hello {{ username }}</p>
{% endif %}
{% if score > 10 %}
<p>You are doing great.</p>
{% else if score > 50 %}
<p>You are freaking amazing!</p>
{% endif %}
<p>This is your <strong>awesome</strong> profile page.</p>
{% if not email %}
<p>Please consider setting your email address</p>
{% endif %}
{% if balance > 0 %}
<p>You are ready to go!</p>
{% else %}
<p>No balance</p>
{% endif %}
And the output would be the following:
{% if username %}
<p>Hello {{ username }}</p>
{% else %}<div class="empty">Empty</div>{% endif %}
{% if score > 10 %}
<p>You are doing great.</p>
{% else if score > 50 %}
<p>You are freaking amazing!</p>
{% endif %}
<p>This is your <strong>awesome</strong> profile page.</p>
{% if not email %}
<p>Please consider setting your email address</p>
{% else %}<div class="empty">Empty</div>{% endif %}
{% if balance > 0 %}
<p>You are ready to go!</p>
{% else %}
<p>No balance</p>
{% endif %}
In short, if the contents inside the if block doesn't have a conditional, then the extra string is appended right before the closing tag. Hope that makes sense. I know it's a lot to ask for, but could someone just get me started with this in the right direction? I'm not very good with regex using JavaScript, and it's basically kicking my ass. Thanks for any help!
I would do like the following. Flag "g" is global, "m" is multiline and "s" is "dotall" mode which means that "." can grab "\n". I grab all the inputs, replace them, see if there's "else if" or "else" therefore replace "{% endif %}" with "{% else %}" plus what you wanted plus "{% endif %}".
input.replace(
/{% if.*?%}.*?{% endif %}/gms,
match =>
(!/(else if|else)/.test(match))
? match.replace(
/{% endif %}/,
'{% else %}<div class="empty">Empty</div>{% endif %}'
)
: match
);
/*{% if username %}
<p>Hello {{ username }}</p>
{% else %}<div class="empty">Empty</div>{% endif %}
{% if score > 10 %}
<p>You are doing great.</p>
{% else if score > 50 %}
<p>You are freaking amazing!</p>
{% endif %}
<p>This is your <strong>awesome</strong> profile page.</p>
{% if not email %}
<p>Please consider setting your email address</p>
{% else %}<div class="empty">Empty</div>{% endif %}
{% if balance > 0 %}
<p>You are ready to go!</p>
{% else %}
<p>No balance</p>
{% endif %}*/
Related
this is in additional scripts section of shopify and im trying to send a pixel event for certain rules. i have pricing rules in place which work fine but this one isnt saving(assuming because it's wrong
{% for line in checkout.line_items %}
{% assign found_collection = false %}
{% for collection in line.product.collections %}
{% if collection.title == 'Collection NAME' %}
{% assign found_collection = true %}
{% endif %}
{% endfor %}
{% if found_collection == true %}
I'm building a web app using the Django framework. I'm attempting to use some JavaScript to disable a button that users can press to submit a text-based review.
The JavaScript in the listing.js file looks as follows:
document.addEventListener('DOMContentLoaded', function () {
hide_submit_review_button();
});
// Hide the 'Submit Review'button until the user begins typing a review
// Prevent the user from typing more than 100 characters
function hide_submit_review_button() {
var submit_review_button = document.getElementById('submit-review-button');
if (submit_review_button !== null) {
document.getElementById('submit-review-button').disabled = true;
document.getElementById('review-contents').onkeyup = () => {
if ((document.getElementById('review-contents').value.length > 0 &&
document.getElementById('review-contents').value.length <= 100 )) {
document.getElementById('submit-review-button').disabled = false;
} else {
document.getElementById('submit-review-button').disabled = true;
}
};
}
}
In my listing.html file, I identify the review-contents and submit-review-button. Here's the code:
{% extends "layout.html" %}
{% load static %}
{% block body %}
{% if user.is_authenticated %}
<form action="{% url 'review' listing.id %}" method="POST">
{% csrf_token %}
<input type="text" class="form-control" name="review" id="review-contents" placeholder="Write a review...">
<input class="btn btn-primary mt-1" type="submit" id="submit-review-button" value="Submit Review">
</form>
{% endif %}
{% endblock %}
{% block script %}
{% if user.is_authenticated %}
{{ block.super }}
<script src="{% static 'listing.js' %}"></script>
{% endif %}
{% endblock %}
An example of a page where the button appears is: http://127.0.0.1:8000/listings/7
And, here is what the urls.py file looks like (if it matters):
urlpatterns = [
path('', views.index, name='index'),
path('listings/<int:listing_id>', views.listing, name='listing'),
]
Can anyone see why this button doesn't disable?
Thanks!
The problem resulted from not having the following in the header tag in the layout.html file:
{% block script %}
{% endblock %}
i was wondering if there is a way i can change the body of for loop in django using javascript each time i press a button.
in my case i want to display matches this week and when i press next i want to change the list using javascript and then pass it django template in the regroup part, i want to change the matches list.
i know how to write the code to make the new list and the previous and next buttons using javascript but i don't know how to pass it to django template
or maybe another way could be to write django code in javascript, anyone can help with either way?
in views.py , matches return a list of dictionaries from today to 6 days later
def home(request):
start = datetime.now().date()
end = today + timedelta(6)
matches = request_games(today, after_week)
return render(request, "sporty/home.html",{
"matches": matches,
"start" : start,
"end": end
})
in home.html
{% extends "sporty/layout.html" %}
{% load static %}
{% block body %}
<div class="box">
{{start}},{{end}}
{% regroup matches by date as date_list %}
{% for date in date_list %}
<div class="the_date">
{{date.grouper}}
</div>
{% for match in date.list %}
<div class="match_container">
<div class="status">
{% if match.status_code == 1%}
{{match.minute}}'
{% elif match.status_code == 11%}
HT
{% elif match.status_code == 3 %}
Finished
{% endif %}
</div>
<div class="match">
<div class="home">
{{match.home_name}} <img src="{{match.home_logo}}">
</div>
<div class="score">
{% if match.status_code == 0 %}
{{match.time}}
{% elif match.status_code == 17 %}
TBD
{% elif match.status_code == 1%}
{{match.home_score}} : {{match.away_score}}
{% elif match.staus_code == 11%}
{{match.home_score}} : {{match.away_score}}
{% elif match.status_code == 3 %}
{{match.home_score}} : {{match.away_score}}
{% endif %}
</div>
<div class="away">
<img src="{{match.away_logo}}">
{{match.away_name}}
</div>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
{% endblock %}
def request_games(start, end):
params = (
("season_id","1511"),
("date_from",start.strftime("%Y-%m-%d")),
("date_to",end.strftime("%Y-%m-%d"))
);
headers = {
"apikey": //my api key
}
response = requests.get('https://app.sportdataapi.com/api/v1/soccer/matches', headers=headers, params=params)
r = response.json()
data = r["data"]
number = len(data)
matches = []
for i in range(number):
match = {}
match['status'] = data[i]["status"]
match['status_code'] = data[i]["status_code"]
match['minute'] = data[i]['minute']
full_date = data[i]["match_start"]
dt = datetime.strptime(full_date, '%Y-%m-%d %H:%M:%S')
match['date'] = dt.date()
match['time'] = dt.time()
match['start'] = full_date
home_team = data[i]["home_team"]
match['home_name'] = home_team['name']
match['home_logo'] = home_team['logo']
away_team = data[i]["away_team"]
match['away_name'] = away_team['name']
match['away_logo'] = away_team['logo']
stats = data[i]['stats']
match['home_score'] = stats['home_score']
match['away_score'] = stats['away_score']
matches.append(match)
matches.sort(key = lambda x: datetime.strptime(x['start'], '%Y-%m-%d %H:%M:%S'))
return matches
First thing first, once you decide to start working on pages that do not refresh but still query the server and change, one of your solutions is to start using AJAX calls to query the server for different data.
This would add a bit of code to your project.
For example, your home.html template will need to be split into two. Make sure to also add jQuery to your head.
sporty/home.html
{% extends "sporty/layout.html" %}
{% load static %}
{% block body %}
<div id="matchweek" class="box">
{% include "sporty/matchweek.html" %}
</div>
<button type="button" value="p" onclick="weekControl(this)">Previous</button>
<button type="button" value="n" onclick="weekControl(this)">Next</button>
{% comment %}
Either place weekupdate.js in /static/ or give the path within static,
best would be to have a folder for javascript in static and use 'js/weekupdate.js'
{% endcomment %}
<script src="{% static 'js/weekupdate.js' %}"></script>
{% endblock %}
and sporty/matchweek.html
{{start}},{{end}}
{% regroup matches by date as date_list %}
{% for date in date_list %}
<div class="the_date">
{{date.grouper}}
</div>
{% for match in date.list %}
<div class="match_container">
<div class="status">
{% if match.status_code == 1%}
{{match.minute}}'
{% elif match.status_code == 11%}
HT
{% elif match.status_code == 3 %}
Finished
{% endif %}
</div>
<div class="match">
<div class="home">
{{match.home_name}} <img src="{{match.home_logo}}">
</div>
<div class="score">
{% if match.status_code == 0 %}
{{match.time}}
{% elif match.status_code == 17 %}
TBD
{% elif match.status_code == 1%}
{{match.home_score}} : {{match.away_score}}
{% elif match.staus_code == 11%}
{{match.home_score}} : {{match.away_score}}
{% elif match.status_code == 3 %}
{{match.home_score}} : {{match.away_score}}
{% endif %}
</div>
<div class="away">
<img src="{{match.away_logo}}">
{{match.away_name}}
</div>
</div>
</div>
{% endfor %}
{% endfor %}
Because you will need to update the entire content of matchweek div every time.
views.py
def home(request):
if request.is_ajax():
template = 'matchweek.html'
direction = request.GET.get('dir')
if direction == 'n':
request.session['weekoffset'] += 1
elif direction == 'p':
request.session['weekoffset'] -= 1
else:
template = 'home.html'
request.session['weekoffset'] = 0
offset = request.session['weekoffset']
start = datetime.now().date() + timedelta(days=7*offset)
end = start + timedelta(days=6)
matches = request_games(start, end)
return render(request, f"sporty/{template}",{
"matches": matches,
"start": start,
"end": end
})
What you see in the function is a check if the request is coming from the AJAX call or not and determination on what to do from there.
/static/js/weekupdate.js
function weekControl(id) {
var value = id.value;
$.ajax({
url: '', // The url suffix that leads to your home function, example: '/home/'
type: "GET", // Http method
data: {'dir': value}, // The data to be sent to the server.
success: function (htmlres) { // What to do on success and response reaching back
$("#matchweek").html(htmlres);
}
});
}
What you see here is the AJAX get call to your django view with the data of 'dir' and its value. When it is returned, jQuery will change the content of the matchweek div with the new content.
I haven't tested this but let me know if this works and if you have any questions.
I have a site with Drupal 8.9 and Twig Tweak.
I created 7 view blocks to set up a task list in stores. I want to display a task counter for my current user on my home page.
The tasks checks :
If the store has no product (danger).
If a product has no product variation (danger).
If an order does not have the processed status (danger).
If the store does not have a delivery method (danger).
If the store does not have a payment gateway (danger).
If a product from the store is not published (warning).
If the store owner does not have the "merchant" role (warning).
I created a display mode in the types of stores, which I rewrite (integrating the 7 task blocks) with the following code :
commerce-store--professionnel--tasks-frontpage.html.twig
{% set warnings = 0 %}
{% if drupal_view_result('boutique_page_liste_des_taches_produit_non_publie', 'block_1') is not empty %}
{% set warnings = warnings + 1 %}
{% endif %}
{% if drupal_view_result('boutique_page_liste_des_taches_role_marchand', 'block_1') is empty %}
{% set warnings = warnings + 1 %}
{% endif %}
{% set dangers = 0 %}
{% if drupal_view_result('boutique_page_liste_des_taches_aucun_produit', 'block_1', store_entity.id()) is empty %}
{% set dangers = dangers + 1 %}
{% endif %}
{% if drupal_view_result('boutique_page_liste_des_taches_aucune_variation', 'block_1', store_entity.id()) is not empty %}
{% set dangers = dangers + 1 %}
{% endif %}
{% if drupal_view_result('boutique_page_liste_des_taches_commande', 'block_1', store_entity.id()) is not empty %}
{% set dangers = dangers + 1 %}
{% endif %}
{% if drupal_view_result('boutique_page_liste_des_taches_mode_de_livraison', 'block_1', store_entity.id()) is empty %}
{% set dangers = dangers + 1 %}
{% endif %}
{% if drupal_view_result('boutique_page_liste_des_taches_passerelle_de_paiement', 'block_1', store_entity.id()) is empty %}
{% set dangers = dangers + 1 %}
{% endif %}
{% if dangers or warnings > 0 %}
<div class="alert alert-light border overflow-hidden shadow rounded hover mt-5 mb-0" role="alert">
<div>
<i class="fas fa-tasks fa-2x mr-4 float-left"></i>
<div class="alert-heading h5 mt-0 mb-2">Des tâches requièrent votre attention dans votre <span class="text-lowercase">{{ store_entity.type.entity.label }}</span> "{{ store_entity.name.value }}".</div>
<small>Veuillez passer en revue cette liste.</small>
</div>
<hr class="mt-3 mb-3 border">
<div class="d-flex justify-content-around">
{% if dangers > 0 %}
<p class="text-center mb-0"><i class="fas fa-times-circle fa-2x text-danger"></i><br>{{ dangers }} importante{% if dangers > 1 %}s{% endif %}</p>
{% endif %}
{% if warnings > 0 %}
<p class="text-center mb-0"><i class="fas fa-exclamation-circle fa-2x text-warning"></i><br>{{ warnings }} avertissement{% if warnings > 1 %}s{% endif %}</p>
{% endif %}
</div>
</div>
{% endif %}
{# /** TEST */ #}
{{ drupal_view('boutique_page_liste_des_taches_role_marchand', 'block_1', store_entity.id()) }}
I created a view block to display the stores of the current user :
https://i.stack.imgur.com/MpANw.png
I integrated this block to my home page :
page--front.html.twig
<div class="main-timeline">
{{ drupal_view('accueil_page_liste_des_taches_utilisateur', 'block_1') }}
{{ drupal_view('accueil_page_liste_des_taches_boutique', 'block_1') }}
{{ drupal_view('accueil_page_liste_des_taches_groupe', 'block_1') }}
{{ drupal_view('message_activity_stream_timeline_private', 'block_1') }}
</div>
I have disabled the cache for all views :
https://i.stack.imgur.com/JkhhN.png
Great, the counter works :
https://i.stack.imgur.com/QuQC2.png
My problem :
The counter never changes, to update it I have to do a drush cr.
How to correct this problem ?
Maybe I should add something to my .theme file.
To deactivate the cache of this template.
Or update this code with JS.
I DON'T WANT TO DESECTIVATE THE COVER FOR THE WHOLE SITE, BUT ONLY ON THE COUNTER.
Just for information, here is what the list of stains in a store looks like :
https://i.stack.imgur.com/xCqkx.png
UPDATE :
I added this code at the end of the commerce-store--professionnel--tasks-frontpage.html.twig template.
Only this block is updated without any problems. For the rest of the code, it is cache and there is no update without clearing the cache manually.
It seems that the code adds them to the code (the counting functionality) is problematic.
{# /** TEST */ #}
{{ drupal_view('boutique_page_liste_des_taches_role_marchand', 'block_1', store_entity.id()) }}
https://i.stack.imgur.com/Q146k.png
I did not clear the cache. The counter is not updated. The added block is updated.
https://i.stack.imgur.com/cW14w.png
am getting this error trying to set a blog category page
NoReverseMatch at /blog/
Reverse for 'category_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['blog\/category\-detail\/(?P[-a-zA-Z0-9_]+)$']
Here is my url.py
from django.urls import path,include
from .import views
urlpatterns = [
path('blog/',views.post_list,name="post_list"),
path('blog/post-detail/<slug:slug>',views.post_detail,name="post_detail"),
path('blog/category-detail/<slug:slug>',views.category_detail,name="category_detail"),
]
views.py
from django.shortcuts import render,get_object_or_404
from.models import Post,Category
# Create your views here.
def post_list(request):
object_list=Post.objects.all()
context={
'object_list': object_list,
}
return render(request,"blog.html",context)
def post_detail(request,slug=None):
post=get_object_or_404(Post,slug=slug)
context={
'post':post,
}
return render(request,"post_detail.html",context)
def category_detail(request,slug=None):
category=get_object_or_404(Category,slug=slug)
post=Post.objects.filter(category=category,status='Published')
context={
'category':category,
'post':post,
}
return render(request,"category_detail.html",context)
blog.html
{% for obj in object_list %}
{% if obj.status == 'Published' %}
<article>
<div class="embed-responsive embed-responsive-16by9">
<img src="images/blog1.jpg" alt="" />
</div>
<div class="post-content">
<h2>{{obj.title}}</h2>
<div>
{{obj.created}} Author {{obj.user}} <h4>{{obj.Category}}</h4>
<hr/>
<p>{{obj.body}}</p>
<a class="mtr-btn button-navy ripple" href= "{% url 'post_detail' obj.slug %}">Continue reading →</a><br>
</div>
</article>
{% endif %}
{% endfor %}
category_detail.html
{% extends "base.html" %}
{% load static %}
{% block seo_title %}{{category.seo_title}}{% endblock %}
{% block seo_description %}{{category.seo_description}}{% endblock %}
{% block Content %}
<h2>{{category.title}}</h2>
<p>{{category.description}}</p>
{% for item in post %}
{{item.title}}
{{item.body|truncatechars:50}}
{% endfor %}
{% endblock Content %}
NOTE THE OTHER VIEWS.PY ARE WORKING FINE JUST THE category_detail function
As the error said, the argument is missing here. Maybe you need to change {% url 'category_detail' slug=post.Category.slug %} with {% url 'category_detail' slug=obj.category.slug %} because I do not see any post variable reference in the blog.html template.
update
You have not shared your Model codes, but I am assuming your Post Model has Foreign Key to Category Model and it looks like Category=models.ForeignKey(Category). So you need to update the view like this:
def category_detail(request,slug=None):
category=get_object_or_404(Category,slug=slug)
post=Post.objects.filter(Category=category,status='Published')