Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pystache_custom
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenEdx
pystache_custom
Commits
20bec630
Commit
20bec630
authored
Aug 23, 2011
by
Kenneth Reitz
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
style and import changes
parent
8ca7408f
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
145 additions
and
60 deletions
+145
-60
pystache/loader.py
+31
-14
pystache/template.py
+45
-17
pystache/view.py
+69
-29
No files found.
pystache/loader.py
View file @
20bec630
# -*- coding: utf-8 -*-
"""
pystache.loader
~~~~~~~~~~~~~~~
This module provides Pystache's Loader class.
"""
import
os
class
Loader
(
object
):
template_extension
=
'mustache'
template_path
=
'.'
template_encoding
=
None
def
load_template
(
self
,
template_name
,
template_dirs
=
None
,
encoding
=
None
,
extension
=
None
):
'''Returns the template string from a file or throws IOError if it non existent'''
"""Returns the template string from a file, or throws IOError
if it is non-existent.
"""
if
None
==
template_dirs
:
template_dirs
=
self
.
template_path
if
encoding
is
not
None
:
self
.
template_encoding
=
encoding
if
extension
is
not
None
:
self
.
template_extension
=
extension
file_name
=
template_name
+
'.'
+
self
.
template_extension
# Given a single directory
we'll load from it
# Given a single directory
, we'll load from it.
if
isinstance
(
template_dirs
,
basestring
):
file_path
=
os
.
path
.
join
(
template_dirs
,
file_name
)
return
self
.
_load_template_file
(
file_path
)
# Given a list of directories
we'll check each for our file
# Given a list of directories
, we'll check each for our file.
for
path
in
template_dirs
:
file_path
=
os
.
path
.
join
(
path
,
file_name
)
if
os
.
path
.
exists
(
file_path
):
return
self
.
_load_template_file
(
file_path
)
raise
IOError
(
'"
%
s" not found in "
%
s"'
%
(
template_name
,
':'
.
join
(
template_dirs
),))
def
_load_template_file
(
self
,
file_path
):
'''Loads and returns the template file from disk'''
"""Loads and returns the template file from disk."""
f
=
open
(
file_path
,
'r'
)
try
:
template
=
f
.
read
()
if
self
.
template_encoding
:
template
=
unicode
(
template
,
self
.
template_encoding
)
finally
:
f
.
close
()
return
template
\ No newline at end of file
pystache/template.py
View file @
20bec630
# -*- coding: utf-8 -*-
import
re
import
cgi
import
collections
import
os
import
copy
from
.loader
import
Loader
try
:
import
markupsafe
escape
=
markupsafe
.
escape
literal
=
markupsafe
.
Markup
except
ImportError
:
escape
=
lambda
x
:
cgi
.
escape
(
unicode
(
x
))
literal
=
unicode
...
...
@@ -18,15 +19,15 @@ class Modifiers(dict):
"""Dictionary with a decorator for assigning functions to keys."""
def
set
(
self
,
key
):
"""
Decorator function to set the given key to
the decorated function.
>>> modifiers = {}
>>> @modifiers.set('P')
... def render_tongue(self, tag_name=None, context=None):
... return ":P
%
s"
%
tag_name
>>> modifiers
{'P': <function render_tongue at 0x...>}
"""
Decorator function to set the given key to
the decorated function.
>>> modifiers = {}
>>> @modifiers.set('P')
... def render_tongue(self, tag_name=None, context=None):
... return ":P
%
s"
%
tag_name
>>> modifiers
{'P': <function render_tongue at 0x...>}
"""
def
setter
(
func
):
...
...
@@ -35,18 +36,17 @@ class Modifiers(dict):
return
setter
class
Template
(
object
):
tag_re
=
None
otag
=
'{{'
ctag
=
'}}'
modifiers
=
Modifiers
()
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
from
view
import
View
from
.
view
import
View
self
.
template
=
template
...
...
@@ -56,6 +56,7 @@ class Template(object):
self
.
view
=
context
if
isinstance
(
context
,
View
)
else
View
(
context
=
context
)
self
.
_compile_regexps
()
def
_compile_regexps
(
self
):
tags
=
{
'otag'
:
re
.
escape
(
self
.
otag
),
...
...
@@ -68,6 +69,7 @@ class Template(object):
tag
=
r"
%(otag)
s(#|=|&|!|>|\{)?(.+?)\1?
%(ctag)
s+"
self
.
tag_re
=
re
.
compile
(
tag
%
tags
)
def
_render_sections
(
self
,
template
,
view
):
while
True
:
match
=
self
.
section_re
.
search
(
template
)
...
...
@@ -82,18 +84,22 @@ class Template(object):
# Callable
if
it
and
isinstance
(
it
,
collections
.
Callable
):
replacer
=
it
(
inner
)
# Dictionary
elif
it
and
hasattr
(
it
,
'keys'
)
and
hasattr
(
it
,
'__getitem__'
):
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
# Lists
elif
it
and
hasattr
(
it
,
'__iter__'
):
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_list
(
inner
,
it
)
# Other objects
elif
it
and
isinstance
(
it
,
object
):
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
# Falsey and Negated or Truthy and Not Negated
elif
(
not
it
and
section
[
2
]
==
'^'
)
or
(
it
and
section
[
2
]
!=
'^'
):
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
...
...
@@ -102,6 +108,7 @@ class Template(object):
return
template
def
_render_tags
(
self
,
template
):
while
True
:
match
=
self
.
tag_re
.
search
(
template
)
...
...
@@ -116,22 +123,32 @@ class Template(object):
return
template
def
_render_dictionary
(
self
,
template
,
context
):
self
.
view
.
context_list
.
insert
(
0
,
context
)
template
=
Template
(
template
,
self
.
view
)
out
=
template
.
render
()
self
.
view
.
context_list
.
pop
(
0
)
return
out
def
_render_list
(
self
,
template
,
listing
):
insides
=
[]
for
item
in
listing
:
insides
.
append
(
self
.
_render_dictionary
(
template
,
item
))
return
''
.
join
(
insides
)
@modifiers.set
(
None
)
def
_render_tag
(
self
,
tag_name
):
raw
=
self
.
view
.
get
(
tag_name
,
''
)
# For methods with no return value
...
...
@@ -143,30 +160,41 @@ class Template(object):
return
escape
(
raw
)
@modifiers.set
(
'!'
)
def
_render_comment
(
self
,
tag_name
):
return
''
@modifiers.set
(
'>'
)
def
_render_partial
(
self
,
template_name
):
from
pystache
import
Loader
markup
=
Loader
()
.
load_template
(
template_name
,
self
.
view
.
template_path
,
encoding
=
self
.
view
.
template_encoding
)
markup
=
Loader
()
.
load_template
(
template_name
,
self
.
view
.
template_path
,
encoding
=
self
.
view
.
template_encoding
)
template
=
Template
(
markup
,
self
.
view
)
return
template
.
render
()
@modifiers.set
(
'='
)
def
_change_delimiter
(
self
,
tag_name
):
"""Changes the Mustache delimiter."""
self
.
otag
,
self
.
ctag
=
tag_name
.
split
(
' '
)
self
.
_compile_regexps
()
return
''
@modifiers.set
(
'{'
)
@modifiers.set
(
'&'
)
def
render_unescaped
(
self
,
tag_name
):
"""Render a tag without escaping it."""
return
literal
(
self
.
view
.
get
(
tag_name
,
''
))
def
render
(
self
,
encoding
=
None
):
template
=
self
.
_render_sections
(
self
.
template
,
self
.
view
)
result
=
self
.
_render_tags
(
template
)
...
...
pystache/view.py
View file @
20bec630
from
pystache
import
Template
import
os.path
# -*- coding: utf-8 -*-
"""
pystache.loader
~~~~~~~~~~~~~~~
This module provides Pystache's views.
"""
import
re
from
types
import
*
from
types
import
UnboundMethodType
from
.loader
import
Loader
from
.template
import
Template
def
get_or_attr
(
context_list
,
name
,
default
=
None
):
if
not
context_list
:
return
default
for
obj
in
context_list
:
try
:
return
obj
[
name
]
except
KeyError
:
pass
except
:
try
:
return
getattr
(
obj
,
name
)
except
AttributeError
:
pass
return
default
class
View
(
object
):
"""A Pystache view."""
template_name
=
None
template_path
=
None
template
=
None
template_encoding
=
None
template_extension
=
'mustache'
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
self
.
template
=
template
context
=
context
or
{}
context
.
update
(
**
kwargs
)
context
.
update
(
kwargs
)
self
.
context_list
=
[
context
]
def
get
(
self
,
attr
,
default
=
None
):
attr
=
get_or_attr
(
self
.
context_list
,
attr
,
getattr
(
self
,
attr
,
default
))
if
hasattr
(
attr
,
'__call__'
)
and
type
(
attr
)
is
UnboundMethodType
:
return
attr
()
else
:
return
attr
def
get_template
(
self
,
template_name
):
if
not
self
.
template
:
from
pystache
import
Loader
template_name
=
self
.
_get_template_name
(
template_name
)
self
.
template
=
Loader
()
.
load_template
(
template_name
,
self
.
template_path
,
encoding
=
self
.
template_encoding
,
extension
=
self
.
template_extension
)
self
.
template
=
Loader
()
.
load_template
(
template_name
,
self
.
template_path
,
encoding
=
self
.
template_encoding
,
extension
=
self
.
template_extension
)
return
self
.
template
def
_get_template_name
(
self
,
template_name
=
None
):
"""TemplatePartial => template_partial
Takes a string but defaults to using the current class' name or
the `template_name` attribute
the `template_name` attribute
.
"""
if
template_name
:
return
template_name
...
...
@@ -64,6 +75,7 @@ class View(object):
return
re
.
sub
(
'[A-Z]'
,
repl
,
template_name
)[
1
:]
def
_get_context
(
self
):
context
=
{}
for
item
in
self
.
context_list
:
...
...
@@ -71,12 +83,16 @@ class View(object):
context
.
update
(
item
)
return
context
def
render
(
self
,
encoding
=
None
):
return
Template
(
self
.
get_template
(
self
.
template_name
),
self
)
.
render
(
encoding
=
encoding
)
template
=
Template
(
self
.
get_template
(
self
.
template_name
),
self
)
return
template
.
render
(
encoding
=
encoding
)
def
__contains__
(
self
,
needle
):
return
needle
in
self
.
context
or
hasattr
(
self
,
needle
)
def
__getitem__
(
self
,
attr
):
val
=
self
.
get
(
attr
,
None
)
...
...
@@ -84,11 +100,36 @@ class View(object):
raise
KeyError
(
"Key '
%
s' does not exist in View"
%
attr
)
return
val
def
__getattr__
(
self
,
attr
):
if
attr
==
'context'
:
return
self
.
_get_context
()
raise
AttributeError
(
"Attribute '
%
s' does not exist in View"
%
attr
)
def
__str__
(
self
):
return
self
.
render
()
\ No newline at end of file
return
self
.
render
()
def
get_or_attr
(
context_list
,
name
,
default
=
None
):
"""Returns an attribute from given context."""
if
not
context_list
:
return
default
for
obj
in
context_list
:
try
:
return
obj
[
name
]
except
KeyError
:
pass
except
:
try
:
return
getattr
(
obj
,
name
)
except
AttributeError
:
pass
return
default
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment