HTML Page Loads, but shows up blank - python

I'm working on a project in Python, and I have part of the project working (where the user submits a post). I'm trying to make it so that when the user submits their entry, they get redirected to another page, which shows all the things they've posted. When I test this, I get redirected to the new page I made, but the page is blank. Here is my code:
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
t = jinja_env.get_template(template)
return t.render(params)
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
class Entry(db.Model):
subject = db.StringProperty(required=True)
entry = db.TextProperty(required=True)
created = db.DateTimeProperty(auto_now_add = True)
class MainPage(Handler):
def render_front(self, subject="", entry="", error=""):
blog = db.GqlQuery("SELECT * FROM Entry ORDER BY created DESC LIMIT 10")
self.render("entry.html", subject=subject, entry=entry, error=error, blog=blog)
def get(self):
self.render_front()
def post(self):
subject = self.request.get("subject")
entry = self.request.get("entry")
if subject and entry:
e = Entry(subject = subject, entry=entry)
e.put()
self.redirect("/BlogPost")
else:
error = "To post a new entry, you must add both, a subject and your post"
self.render_front(subject, entry, error)
class BlogPost(Handler):
def get(self):
self.render("blogfront.html")
app = webapp2.WSGIApplication([('/', MainPage), ('/BlogPost', BlogPost)], debug = True)
This is just a piece of my code (I believe the error lies somewhere along those lines since my front page is working).
This is my blogfront.html:
<!DOCTYPE html>
<html>
<head>
<title>Blog </title>
</head>
<body>
{% for entry in blog %}
<div class="entry">
<div class="entry-subject">{{entry.subject}}</div>
<label>{{entry.created}}</label>
<hr>
<pre class="entry-body">{{entry.entry}}</pre>
</div>
{% endfor %}
</body>
</html>
entry.html is loading while blogfront.html is not. I'm not sure where I'm going wrong with this. I would appreciate any help. Thanks in advance.

Going by your comments to questioners the issue is that while you define blog in the render_front() method, it's a local variable so it vanishes when the method returns. Try retrieving the data again in your BlogPost() method and pass that as the blog argument to self.render(). Without any blog data the template will indeed render as empty.
So your updated method might read:
class BlogPost(Handler):
def get(self):
blog = db.GqlQuery("SELECT * FROM Entry ORDER BY created DESC LIMIT 10")
self.render("blogfront.html", blog=blog)
assuming that you want to see the same data you display in MainPage(), but you may well want something else.

Related

How to make a 'permalink' detail page displaying two images in Google App Engine webapp2 guestbook tutorial

I'm following the Google App Engine tutorial (here's their complete demo code on GitHub) and would like to:
Allow a guestbook user to upload an extra image in addition to 'avatar' when posting a greeting. This could be called 'other'
After posting a greeting, redirect the user to a greeting detail page with a URL like /greeting/numeric-id instead of the main page listing all greetings.
Display the detail page with images using a Jinja2 template called detail.html
I'm having trouble understanding:
A) How to write the redirect code that is called once a greeting is published so it redirects to a URL like /greeting/numeric-id.
B) How to write the Detail view and template page that the user is redirected to so the greeting id and images are displayed.
Here's a diagram showing what I want to do:
Here's guestbook.py:
import os
import urllib
from google.appengine.api import images
from google.appengine.api import users
from google.appengine.ext import ndb
from google.appengine.ext.webapp import blobstore_handlers
from google.appengine.ext import blobstore
import jinja2
import webapp2
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
DEFAULT_GUESTBOOK_NAME = 'default_guestbook'
def guestbook_key(guestbook_name=None):
"""Constructs a Datastore key for a Guestbook entity with name."""
return ndb.Key('Guestbook', guestbook_name or 'default_guestbook')
class Author(ndb.Model):
"""Sub model for representing an author."""
identity = ndb.StringProperty(indexed=False)
email = ndb.StringProperty(indexed=False)
class Greeting(ndb.Model):
"""A model for representing an individual Greeting entry."""
author = ndb.StructuredProperty(Author)
date = ndb.DateTimeProperty(auto_now_add=True)
avatar = ndb.BlobProperty(indexed=False, required=True)
other = ndb.BlobProperty(indexed=False, required=True)
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.out.write('<html><body>')
guestbook_name = self.request.get('guestbook_name')
greetings = Greeting.query(
ancestor=guestbook_key(guestbook_name)) \
.order(-Greeting.date) \
.fetch(10)
self.response.out.write("""
<form action="/sign?%s"
enctype="multipart/form-data"
method="post">
<label>Avatar:</label>
<input type="file" name="avatar"/><br>
<label>Other Image:</label>
<input type="file" name="other"/><br>
<input type="submit" value="Submit">
</form>
</body>
</html>""" % (urllib.urlencode({'guestbook_name': guestbook_name})))
class Image(webapp2.RequestHandler):
""" Handle image stored as blobs of bytes.
No idea how the template knows to select a particular one. """
def get(self):
avatar_greeting_key = ndb.Key(urlsafe=self.request.get('avatar_id'))
other_greeting_key = ndb.Key(urlsafe=self.request.get('other_id'))
avatar_greeting = avatar_greeting_key.get()
other_greeting = other_greeting_key.get()
if avatar_greeting.avatar:
self.response.headers['Content-Type'] = 'image/png'
self.response.out.write(avatar_greeting.avatar)
elif other_greeting.other:
self.response.headers['Content-Type'] = 'image/png'
self.response.out.write(other_greeting.other)
else:
self.response.out.write('No image')
class Guestbook(webapp2.RequestHandler):
def post(self):
guestbook_name = self.request.get('guestbook_name',
DEFAULT_GUESTBOOK_NAME)
greeting = Greeting(parent=guestbook_key(guestbook_name))
if users.get_current_user():
greeting.author = Author(
identity=users.get_current_user().user_id(),
email=users.get_current_user().email())
avatar = self.request.get('avatar')
avatar = images.resize(avatar, 100, 100)
other = self.request.get('other')
other = images.resize(other, 400, 300)
greeting.avatar = avatar
greeting.other = other
greeting.put()
query_params = {'guestbook_name': guestbook_name}
self.redirect('/greeting/%d' % greeting.key.id())
class Detail(webapp2.RequestHandler):
""" Individual greeting. """
def get(self, *args, **kwargs):
guestbook_name = self.request.get('guestbook_name', DEFAULT_GUESTBOOK_NAME)
greeting = Greeting.get_by_id(args[0],
parent=guestbook_key(guestbook_name))
template_values = {
'greeting': greeting,
}
template = JINJA_ENVIRONMENT.get_template('detail.html')
self.response.write(template.render(template_values))
app = webapp2.WSGIApplication([
('/', MainPage),
('/img', Image),
('/sign', Guestbook),
('/greeting/(\d+)', Detail),
], debug=True)
My detail.html template:
<!DOCTYPE html>
{% autoescape true %}
<html>
<head>
<title>Greeting {{ greeting.id }}</title>
</head>
<body>
<h2>Greeting {{ greeting.id }}</h2>
Avatar: <img src="/img?avatar_id={{ greeting.key.urlsafe() }}">
<br>
Other: <img src="/img?other_id={{ greeting.key.urlsafe() }}">
</body>
</html>
{% endautoescape %}
My app.yaml in case it is useful:
runtime: python27
api_version: 1
threadsafe: true
# Handlers match in order, put above the default handler.
handlers:
- url: /stylesheets
static_dir: stylesheets
- url: /.*
script: guestbook.app
libraries:
- name: webapp2
version: latest
- name: jinja2
version: latest
The Error:
Traceback (most recent call last):
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1535, in __call__
rv = self.handle_exception(request, response, e)
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
rv = self.router.dispatch(request, response)
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/Users/simon/Projects/guestbook/guestbook.py", line 111, in get
self.response.write(template.render(template_values))
File "/Users/simon/Projects/google-cloud-sdk/platform/google_appengine/lib/jinja2-2.6/jinja2/environment.py", line 894, in render
return self.environment.handle_exception(exc_info, True)
File "/Users/simon/Projects/guestbook/detail.html", line 9, in top-level template code
Avatar: <img src="/img?avatar_id={{ greeting.key.urlsafe() }}">
UndefinedError: 'None' has no attribute 'key'
Any help, or even better, example code, would be much appreciated.
A GAE/webapp2 blog tutorial with example code of detail and list views and templates would be great, but perhaps the data structure of the GAE BlobStore is not ideal for a blog?
Update:
If I add the python check code contributed in Dan's answer I get a 500 error instead of the stack trace, and if I try the template checks I get a blank greeting page. I've updated the question with my full code and a diagram explaining what I am trying to do.
I'll start with B:
The error indicates that the greeting value is None, leading to an exception when jinja2 attempts to expand greeting.key in {{ greeting.key.urlsafe() }} during template rendering.
One option is to re-arrange the handler code to prevent rendering that template if the necessary conditions are not met, maybe something along these lines:
...
greeting = Greeting.get_by_id(args[0])
if not greeting or not isinstance(greeting.key, ndb.Key):
# can't render that template, invalid greeting.key.urlsafe()
webapp2.abort(500)
return
template_values = {
'greeting': greeting,
}
template = JINJA_ENVIRONMENT.get_template('detail.html')
self.response.write(template.render(template_values))
...
Alternatively you can wrap the template areas referencing the variables with appropriate checks (IMHO uglier, harder and more fragile, tho - python is way better for this kind of logic than jinja2), something along these lines:
{% if greeting and greeting.key %}<img src="/img?avatar_img_id={{ greeting.key.urlsafe() }}">{% endif %}
Now to A.
In short - not a great idea, primarily because the numeric ID you're trying to use in the URL is not unique except for greetings under the same parent entity!. Which in a way explains why greeting is invalid leading to the error from the B answer.
The greeting = Greeting.get_by_id(args[0]) will return None unless you also created a greeting entity with the ID you're passing in args[0] and no parent!
In order to obtain by ID the greeting you created with:
greeting = Greeting(parent=guestbook_key(guestbook_name))
you'd need to call:
greeting = Greeting.get_by_id(args[0],
parent=guestbook_key(guestbook_name))
You could, if you want to continue in the same direction, also encode the guestbook_name in the greeting URL, which would allow you to also obtain the needed parent key, maybe something along these lines:
/guestbook/<guestbook_name>/greeting/<numeric-id>.
You also need to take a closer look at the image handling. You have architectural inconsistencies: in the diagram and the model you have both the avatar and the other image attached to a single greeting entity, but in the Image handler each of them is attached to a separate greeting. The handler also doesn't map at all to the images' URLs (which also needs additional encodings for the data you need to locate the appropriate image, depending on the architectural decision).
I'm afraid you still have a lot of work to do until you get the entire thing to work, much more than properly fit for a single SO question. Step back, re-think your architecture, split it into smaller pieces, focus on one piece at a time and get it going. After you become familiar with the technology for the various pieces you'll feel better tackling the whole problem at once.

How to remove session variable in a template after it's job is done in django

I have a app called dashboard which is where I redirect all logged in users with an option to add articles by the user.
After the user hits Submit button in the form, the data is sent to /dashboard/article/save URL via POST and after the data is stored, the view returns HttpResponseRedirect to show_dashboard which renders dashboard.html with a session variable result.
In the dashboard template file, I have added a notify.js code to show acknowledgements to user. The problem is if this session var is defined, everytime the dashboard page is showed, the notification is triggered EVEN if the user didn't add an article.
(I'm new to using web frameworks so I do not know how this all works properly)
Some code:
dashboard/models.py:
class Article(models.Model):
id = models.IntegerField(primary_key=True)
ar_title = models.CharField(max_length=25)
ar_data = models.CharField(max_length=500)
user = models.ForeignKey(User,on_delete=models.CASCADE)
def getArticleTitle(self):
return self.title
def getArticleData(self):
return self.title
def getArticleAuthor(self):
return self.user
dashboard/urls.py:
urlpatterns = [
url(r'^$', views.show_dashboard,name='home_dashboard'),
url(r'^profile/save/', views.save_profile,name="save_profile"),
url(r'^newsfeed/', views.get_newsfeed,name="newsfeed",),
url(r'^profile/', views.show_profile,name="show_profile"),
url(r'^article/save/', views.add_new_article,name="add_new_article"),
]
dashboard/views.py:
#login_required
def show_dashboard(request):
return render(request,'dashboard/dashboard.html',{'form':NewArticleForm()})
def add_new_article(request):
if(request.method == 'POST'):
ar_title= request.POST['ar_title']
ar_data = request.POST['ar_data']
user = request.user
form = NewArticleForm(request.POST)
if(form.is_valid()):
Article.objects.create(ar_title=ar_title,ar_data=ar_data,user=user)
request.session["result"] = "add_article_OK"
return HttpResponseRedirect(reverse('home_dashboard'))
dashboard.html:
{% ifequal request.session.result 'add_article_OK' %}
<script>
$.notify("New article added successfully",
{position:"bottom right","className":"success","autoHide":"yes","autoHideDelay":"3000"});
</script>
{% endifequal %}
Now, how do I remove this session value after it has displayed the message? I know del request.session['result'] can be issued but where can I put it in this heirarchy of moves?
Do it in the show_dashboard view.
Instead of getting the value from the session in the template, pop it in the view and pass it to the template; that way you take care of getting and clearing it in one go.
#login_required
def show_dashboard(request):
context = {
'form': NewArticleForm(),
'result': request.session.pop('result', None)
}
return render(request,'dashboard/dashboard.html',context)
...
{% ifequal result 'add_article_OK' %}

Google App Engine: 404 Resource not found

I am trying to build a basic blog model using Google App Engine in Python. However, something's wrong with my code I suppose, and I am getting a 404 error when I try to display all the posted blog entries on a single page. Here's the python code:
import os
import re
import webapp2
import jinja2
from string import letters
from google.appengine.ext import db
template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir), autoescape=True)
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self, template, **params):
t = jinja_env.get_template(template)
return t.render(params)
def render(self, template, **kw):
self.write(self.render_str(template, **kw))
def post_key(name = "dad"):
return db.Key.from_path('blog', name)
class Blogger(db.Model):
name = db.StringProperty()
content = db.TextProperty()
created = db.DateTimeProperty(auto_now_add = True)
def render(self):
self._render_text = self.content.replace('\n', '<br>')
return render_str("post.html", p = self)
class MainPage(Handler):
def get(self):
self.response.write("Visit our blog")
class BlogHandler(Handler):
def get(self):
posts = db.GqlQuery("SELECT * FROM Blogger order by created desc")
self.render("frontblog.html", posts = posts)
class SubmitHandler(Handler):
def get(self):
self.render("temp.html")
def post(self):
name = self.request.get("name")
content = self.request.get("content")
if name and content:
a = Blogger(name = name, content = content, parent = post_key())
a.put()
self.redirect('/blog/%s' % str(a.key().id()))
else:
error = "Fill in both the columns!"
self.render("temp.html", name = name, content = content, error = error)
class DisplayPost(Handler):
def get(self, post_id):
po = Blogger.get_by_id(int(post_id))
if po:
self.render("perma.html", po = po)
else:
self.response.write("404 Error")
app = webapp2.WSGIApplication([('/', MainPage),
('/blog', BlogHandler),
('/blog/submit', SubmitHandler),
('/blog/([0-9]+)', DisplayPost)], debug=True)
After posting my content, it gets redirected to a permalink. However, this is the error I am getting on submitting my post:
404 Not Found
The resource could not be found
Here's the frontblog.html source code, in case that would help:
<!DOCTYPE html>
<html>
<head>
<title>CS 253 Blog</title>
</head>
<body>
<a href="/blog">
CS 253 Blog
</a>
<div id="content">
{% block content %}
{%for post in posts%}
{{post.render() | safe}}
<br></br>
{%endfor%}
{% endblock %}
</div>
</body>
</html>
So basically, I am not being redirected to the permalink page. What seems to be the problem?
When you create your post, you're giving it a parent (not sure why). But when you get it, you do so by the ID only, and don't take into account the parent ID. In the datastore, a key is actually a path consisting of all the parent kinds and IDs/names and then those of the current entity, and to get an object you need to pass the full path.
Possible solutions here:
Drop the parent key, since it isn't doing anything here as you're always setting it to the same value;
Use it when you get the object: Blogger.get_by_id(post_id, parent=parent_key()) - obviously this only works if the parent is always the same;
Use the full stringified key in the path, rather than just the ID, and do Blogger.get(key) - you'll also need to change the route regex to accept alphanumeric chars, eg '/blog/(\w+)', and change the redirect to '/blog/%s' % a.key().

Dynamic navigation in Flask

I have a pretty simple site working in Flask that's all powered from an sqlite db. Each page is stored as a row in the page table, which holds stuff like the path, title, content.
The structure is hierarchical where a page can have a parent. So while for example, 'about' may be a page, there could also be 'about/something' and 'about/cakes'. So I want to create a navigation bar with links to all links that have a parent of '/' (/ is the root page). In addition, I'd like it to also show the page that is open and all parents of that page.
So for example if we were at 'about/cakes/muffins', in addition to the links that always show, we'd also see the link to 'about/cakes', in some manner like so:
- About/
- Cakes/
- Muffins
- Genoise
- Pies/
- Stuff/
- Contact
- Legal
- Etc.[/]
with trailing slashes for those pages with children, and without for those that don't.
Code:
#app.route('/')
def index():
page = query_db('select * from page where path = "/"', one=True)
return render_template('page.html', page=page, bread=[''])
#app.route('/<path>')
def page(path=None):
page = query_db('select * from page where path = "%s"' % path, one=True)
bread = Bread(path)
return render_template('page.html', page=page, crumbs=bread.links)
I already feel like I'm violating DRY for having two functions there. But doing navigation will violate it further, since I also want the navigation on things like error pages.
But I can't seem to find a particularly Flasky way to do this. Any ideas?
The "flasky" and pythonic way will be to use class-based view and templates hierarchy
First of all read documentation on both, then you can refactor your code based on this approach:
class MainPage(MethodView):
navigation=False
context={}
def prepare(self,*args,**kwargs):
if self.navigation:
self.context['navigation']={
#building navigation
#in your case based on request.args.get('page')
}
else:
self.context['navigation']=None
def dispatch_request(self, *args, **kwargs):
self.context=dict() #should nullify context on request, since Views classes objects are shared between requests
self.prepare(self,*args,**kwargs)
return super(MainPage,self).dispatch_request(*args,**kwargs)
class PageWithNavigation(MainPage):
navigation = True
class ContentPage(PageWithNavigation):
def get(self):
page={} #here you do your magic to get page data
self.context['page']=page
#self.context['bread']=bread
#self.context['something_Else']=something_Else
return render_template('page.html',**self.context)
Then you can do following:
create separate pages, for main_page.html and page_with_navigation.html
Then your every page "error.html, page.html, somethingelse.html" based on one of them.
The key is to do this dynamically:
Will modify prepare method a bit:
def prepare(self):
if self.navigation:
self.context['navigation']={
#building navigation
#in your case based on request.args.get('page')
}
else:
self.context['navigation']=None
#added another if to point on changes, but you can combine with previous one
if self.navigation:
self.context['extends_with']="templates/page_with_navigation.html"
else:
self.context['extends_with']="templates/main_page.html"
And your templates:
main_page.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
{% block navigation %}
{% endblock %}
{% block main_content %}
{% endblock %}
</body>
</html>
page_with_navigation.html
{% extends "/templates/main_page.html" %}
{% block navigation %}
here you build your navigation based on navigation context variable, which already passed in here
{% endblock %}
page.html or any other some_page.html. Keep it simple!
Pay attention to first line. Your view sets up which page should go in there and you can easily adjust it by setting navigation= of view-class.
{% extends extends_with %}
{% block main_content %}
So this is your end-game page.
Yo do not worry here about navigation, all this things must be set in view class and template should not worry about them
But in case you need them they still available in navigation context variable
{% endblock %}
You can do it in one function by just having multiple decorators :)
#app.route('/', defaults={'path': '/'})
#app.route('/<path>')
def page(path):
page = query_db('select * from page where path = "%s"' % path, one=True)
if path == '/':
bread = Bread(path)
crumbs = bread.links
else:
bread = ['']
crumbs = None
return render_template('page.html', page=page, bread=bread, crumbs=crumbs)
Personally I would modify the bread function to also work for the path / though.
If it's simply about adding variables to your context, than I would recommend looking at the context processors: http://flask.pocoo.org/docs/templating/#context-processors

Implementing breadcrumbs in Python using Flask?

I want breadcrumbs for navigating my Flask app. An option could be to use a general Python module like bread.py:
The bread object accepts a url string and grants access to the url
crumbs (parts) or url links (list of hrefs to each crumb) .
bread.py generates the breadcrumb from the url path, but I want the elements of the breadcrumb to be the title and link of the previously visited pages.
In Flask, maybe this can be done using a decorator or by extending the #route decorator.
Is there a way to have each call of a route() add the title and link of the page (defined in the function/class decorated with #route) to the breadcrumb? Are there other ways to do it? Any examples of breadcrumbs implemented for Flask?
So you're after "path/history" breadcrumbs, rather than "location" breadcrumbs to use the terminology from the wikipedia article?
If you want to have access to the user's history of visited links, then you're going to have to save them in a session. I've had a go at creating a decorator to do this.
breadcrumb.py:
import functools
import collections
import flask
BreadCrumb = collections.namedtuple('BreadCrumb', ['path', 'title'])
def breadcrumb(view_title):
def decorator(f):
#functools.wraps(f)
def decorated_function(*args, **kwargs):
# Put title into flask.g so views have access and
# don't need to repeat it
flask.g.title = view_title
# Also put previous breadcrumbs there, ready for view to use
session_crumbs = flask.session.setdefault('crumbs', [])
flask.g.breadcrumbs = []
for path, title in session_crumbs:
flask.g.breadcrumbs.append(BreadCrumb(path, title))
# Call the view
rv = f(*args, **kwargs)
# Now add the request path and title for that view
# to the list of crumbs we store in the session.
flask.session.modified = True
session_crumbs.append((flask.request.path, view_title))
# Only keep most recent crumbs (number should be configurable)
if len(session_crumbs) > 3:
session_crumbs.pop(0)
return rv
return decorated_function
return decorator
And here's a test application that demonstrates it. Note that I've just used Flask's built-in client side session, you'd probably want to use a more secure server-side session in production, such as Flask-KVsession.
#!/usr/bin/env python
import flask
from breadcrumb import breadcrumb
app = flask.Flask(__name__)
#app.route('/')
#breadcrumb('The index page')
def index():
return flask.render_template('page.html')
#app.route('/a')
#breadcrumb('Aardvark')
def pagea():
return flask.render_template('page.html')
#app.route('/b')
#breadcrumb('Banana')
def pageb():
return flask.render_template('page.html')
#app.route('/c')
#breadcrumb('Chimp')
def pagec():
return flask.render_template('page.html')
#app.route('/d')
#breadcrumb('Donkey')
def paged():
return flask.render_template('page.html')
if __name__ == '__main__':
app.secret_key = '83cf5ca3-b1ee-41bb-b7a8-7a56c906b05f'
app.debug = True
app.run()
And here's the contents of templates/page.html:
<!DOCTYPE html>
<html>
<head><title>{{ g.title }}</title></head>
<body>
<h1>{{ g.title }}</h1>
<p>Breadcrumbs:
{% for crumb in g.breadcrumbs %}
{{ crumb.title }}
{% if not loop.last %}ยป{% endif %}
{% endfor %}
</p>
<p>What next?</p>
<ul>
<li>Aardvark?</li>
<li>Banana?</li>
<li>Chimp?</li>
<li>Donkey?</li>
</ul>
</body>
</html>
i was trying to use the breadcrumb.py , but i was need to check:
if the new item "item = (flask.request.path, view title) " is already exist in the session crumbs, then i will delete all other items frome the index to the end, i do this for Avoid repetition in my session crumds.
flask.session.modified = True
item = (flask.request.path, view_title)
try:
if not item in session_crumbs:
session_crumbs.append(item)
else:
index = session_crumbs.index(item)
session_crumbs = session_crumbs[:index+1]
except:
pass
return rv
return decorated_function
return decorator

Categories