gdritter repos frony-ritter-designs / ef7946c
Start to switch to Mustache templates Getty Ritter 4 years ago
5 changed file(s) with 160 addition(s) and 29 deletion(s). Collapse all Expand all
33 import flask
44 import web
55 import markdown
6 import pystache
67 import storage
78 import sys
89
910 web.template.ALLOWED_AST_NODES.append('Constant')
1011
12 class Templates:
13 renderer = pystache.Renderer()
14
15 def load_template(name):
16 with open(f"templates/{name}.mustache") as f:
17 parsed = pystache.parse(f.read())
18 return lambda stuff: Templates.renderer.render(parsed, stuff)
19
20 main = load_template('main')
21 design_page = load_template('design_page')
1122
1223 def slugify(string):
1324 def process(char):
3041
3142
3243 db = storage.DB()
33 render = web.template.render('templates/',
44 render = web.template.render('old_templates/',
3445 globals=dict(markdown=markdown.markdown,
3546 slugify=slugify,
3647 all_categories=db.all_categories,
4960
5061 def main(func):
5162 def new_func(*args, **kwargs):
52 web.header('Content-Type', 'application/xhtml+xml')
53 return render.main(*func(*args, **kwargs))
63 title, content = func(*args, **kwargs)
64 return Templates.main({'title': title, 'content': content})
5465 new_func.__name__ = func.__name__
5566 return new_func
5667
6071 def GET(self):
6172 try:
6273 pg = db.get_page('main')
63 return ('Frony Ritter Designs',
64 markdown.markdown(pg.text))
74 return 'Frony Ritter Designs', markdown.markdown(pg.text)
6575 except:
6676 raise web.notfound()
6777
6878
6979 class contact:
70
7180 @main
7281 def GET(self):
7382 return 'Contact Information', 'Send me an email at my email address.'
7483
7584
7685 class design:
77
7886 @main
7987 def GET(self, id, slug=None):
80 try:
81 id = int(id)
82 design = db.get_design(id)
83 return 'Designs', render.design_page(*design)
84 except:
85 raise web.notfound()
88 id = int(id)
89 design = db.get_design(id)
90 print(design)
91 return 'Designs', Templates.design_page(design)
8692
8793 def POST(self, id, slug='electric-boogaloo'):
8894 try:
437443
438444 )
439445
440 # app = web.application(urls, globals())
446 app = web.application(urls, globals())
441447 # # web.wsgi.runwsgi = lambda func, addr=None: web.wsgi.runfcgi(func, addr)
442448
443 # if __name__ == '__main__':
444 # app.run()
449 if __name__ == '__main__':
450 app.run()
1 import markdown
12 import os
23 import web
34 from PIL import Image
45
6 import typing
7
8 class Image(typing.NamedTuple):
9 image: str
10
11 class PageContent:
12 def __init__(self, source):
13 self.source = source
14 self.rendered = markdown.markdown(source)
15
16 class Design(typing.NamedTuple):
17 title: str
18 images: typing.List[Image]
19 description: PageContent
20 category: str
21 id: int
22
523 THUMB_SIZE = (100, 100)
6
724
825 class DB:
926
4663 return None
4764 else:
4865 d = d[0]
49 return (d.title,
50 self.get_all_photos_for_design(d.id),
51 d.description,
52 self.get_category_name(d.category),
53 d.id)
66 return Design(title=d.title,
67 images=self.get_all_photos_for_design(d.id),
68 description=PageContent(d.description),
69 category=self.get_category_name(d.category),
70 id=d.id)
5471
5572 def put_design(self, id, title, description, category):
5673 description = description.replace('\r\n', '\n')
7996 def get_all_photos(self, offset=0, pp=None):
8097 if not pp:
8198 pp = self.per_page
82 ps = list(self._db.select('photos',
83 offset=offset * pp,
84 limit=pp,
85 order='id DESC'))
86 return ps
99 return [
100 Image(l) for l
101 in self._db.select('photos',
102 offset=offset * pp,
103 limit=pp,
104 order='id DESC')
105 ]
87106
88107 def get_all_photos_for_design(self, id):
89 return list(d.filename for d in self._db.where('photos',
90 design_id=id))
108 return list(Image(d.filename) for d in self._db.where('photos',
109 design_id=id))
91110
92111 def get_all(self, offset=0, pp=None):
93112 if not pp:
1 <div id="photo">
2 <img src="/static/frony.png" />
3 </div>
4 <div id="about-block">
5 {{{text}}}
6 </div>
1 <div class="design">
2 <div class="title">{{title}}</div>
3 <div class="images">
4 {{#images}}
5 <img src="/static/photos/{{image}}" />
6 {{/images}}
7 </div>
8 <div class="description">{{#description}}{{{ rendered }}}{{/description}}</div>
9 <div class="related">
10 <a href="/category/{{category}}/">{{category}}</a>
11 </div>
12 </div>
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <script>
5 /* Google Analytics malarkey */
6 (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
7 (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
8 m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
9 })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
10
11 ga('create', 'UA-43663896-1', 'fronyritterdesigns.com');
12 ga('send', 'pageview');
13 </script>
14 <meta http-equiv="Content-Type" contents="application/xhtml+xml; charset=utf-8;" />
15 <meta name="description" content="Cross-Stitch Patterns and Other Crafts from Frony Ritter Designs" />
16 <link rel="stylesheet" type="text/css" href="/static/standard.css" />
17 <title>Frony Ritter Designs &ndash; $title</title>
18 </head>
19 <body>
20 <div id="page">
21 <div id="header">
22 <p>
23 <a href="/"><img src="/static/frd_logo.png"/></a>
24 </p>
25 <p>{{ title }}</p>
26 </div>
27 <div id="sidebyside">
28 <div class="topnav">
29 <ul>
30 <a href="/"><li class="topitem">Home</li></a>
31 <a href="http://blog.fronyritterdesigns.com/"><li class="topitem">Blog</li></a>
32
33 <a href="/category/charts"><li class="topitem">Cross-Stitch Charts</li></a>
34
35 <ul>
36 <a href="/category/charts/tag/celtic"><li class="topitem">Celtic Series</li></a>
37 <a href="/category/charts/tag/spring"><li class="topitem">Spring Series</li></a>
38 <a href="/category/charts/tag/summer"><li class="topitem">Summer Series</li></a>
39 <a href="/category/charts/tag/fall"><li class="topitem">Fall Series</li></a>
40 <a href="/category/charts/tag/winter"><li class="topitem">Winter Series</li></a>
41 <a href="/category/charts/tag/flags"><li class="topitem">Flags</li></a>
42 <a href="/category/charts/tag/booklets"><li class="topitem">Booklets</li></a>
43 <a href="/category/charts/tag/kits"><li class="topitem">Kits</li></a>
44 <a href="/category/charts/tag/minis"><li class="topitem">Minis</li></a>
45 <a href="/category/charts/tag/large"><li class="topitem">Large Charts</li></a>
46 <a href="/category/charts/tag/recipe"><li class="topitem">Small-Batch Recipe</li></a>
47 </ul>
48
49 <a href="/category/papercrafting" ><li class="topitem" >Papercraft Ideas</li></a>
50 <ul>
51 <a href="/tag/cards"><li class="topitem">Cards</li></a>
52 <a href="/tag/tags"><li class="topitem">Tags</li></a>
53 <a href="/tag/placecards"><li class="topitem">Placecards</li></a>
54 <a href="/tag/boxes"><li class="topitem">Boxes</li></a>
55 <a href="/tag/bags"><li class="topitem">Bags</li></a>
56 </ul>
57
58 <a href="/category/beading" ><li class="topitem" >Beading</li></a>
59
60 <a href="/category/paintings"><li class="topitem">Painting</li></a>
61
62 <a href="/tag/free"><li class="topitem">Free Patterns</li></a>
63 <ul>
64 <a href="/category/charts/tag/free"><li class="topitem">Cross-Stitch</li></a>
65 <a href="/category/paintings/tag/free"><li class="topitem">Painting</li></a>
66 <a href="/category/beading/tag/free"><li class="topitem">Beading</li></a>
67 </ul>
68
69 <a href="/category/gallery"><li class="topitem">Stitchers' Gallery</li></a>
70
71 <a href="/wheretobuy"><li class="topitem">Where To Buy</li></a>
72 <a href="/retailinfo"><li class="topitem">Info For Retailers</li></a>
73 <a href="/corrections/"><li class="topitem">Corrections</li></a>
74 <a href="/about/"><li class="topitem">About</li></a>
75
76 </ul>
77 </div>
78 <div id="contents">
79 {{{ content }}}
80 </div>
81 <div style="clear: both;"></div>
82 </div>
83 <div id="footer">
84 &copy;2020 | <a href="/about/">About</a> | <a href="/contact/">Contact</a>
85 </div>
86 </div>
87 </body>
88 </html>