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
import
os
class
Loader
(
object
):
class
Loader
(
object
):
template_extension
=
'mustache'
template_extension
=
'mustache'
template_path
=
'.'
template_path
=
'.'
template_encoding
=
None
template_encoding
=
None
def
load_template
(
self
,
template_name
,
template_dirs
=
None
,
encoding
=
None
,
extension
=
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
:
if
None
==
template_dirs
:
template_dirs
=
self
.
template_path
template_dirs
=
self
.
template_path
if
encoding
is
not
None
:
if
encoding
is
not
None
:
self
.
template_encoding
=
encoding
self
.
template_encoding
=
encoding
if
extension
is
not
None
:
if
extension
is
not
None
:
self
.
template_extension
=
extension
self
.
template_extension
=
extension
file_name
=
template_name
+
'.'
+
self
.
template_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
):
if
isinstance
(
template_dirs
,
basestring
):
file_path
=
os
.
path
.
join
(
template_dirs
,
file_name
)
file_path
=
os
.
path
.
join
(
template_dirs
,
file_name
)
return
self
.
_load_template_file
(
file_path
)
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
:
for
path
in
template_dirs
:
file_path
=
os
.
path
.
join
(
path
,
file_name
)
file_path
=
os
.
path
.
join
(
path
,
file_name
)
if
os
.
path
.
exists
(
file_path
):
if
os
.
path
.
exists
(
file_path
):
return
self
.
_load_template_file
(
file_path
)
return
self
.
_load_template_file
(
file_path
)
raise
IOError
(
'"
%
s" not found in "
%
s"'
%
(
template_name
,
':'
.
join
(
template_dirs
),))
raise
IOError
(
'"
%
s" not found in "
%
s"'
%
(
template_name
,
':'
.
join
(
template_dirs
),))
def
_load_template_file
(
self
,
file_path
):
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'
)
f
=
open
(
file_path
,
'r'
)
try
:
try
:
template
=
f
.
read
()
template
=
f
.
read
()
if
self
.
template_encoding
:
if
self
.
template_encoding
:
template
=
unicode
(
template
,
self
.
template_encoding
)
template
=
unicode
(
template
,
self
.
template_encoding
)
finally
:
finally
:
f
.
close
()
f
.
close
()
return
template
return
template
\ No newline at end of file
pystache/template.py
View file @
20bec630
# -*- coding: utf-8 -*-
import
re
import
re
import
cgi
import
cgi
import
collections
import
collections
import
os
import
copy
from
.loader
import
Loader
try
:
try
:
import
markupsafe
import
markupsafe
escape
=
markupsafe
.
escape
escape
=
markupsafe
.
escape
literal
=
markupsafe
.
Markup
literal
=
markupsafe
.
Markup
except
ImportError
:
except
ImportError
:
escape
=
lambda
x
:
cgi
.
escape
(
unicode
(
x
))
escape
=
lambda
x
:
cgi
.
escape
(
unicode
(
x
))
literal
=
unicode
literal
=
unicode
...
@@ -18,15 +19,15 @@ class Modifiers(dict):
...
@@ -18,15 +19,15 @@ class Modifiers(dict):
"""Dictionary with a decorator for assigning functions to keys."""
"""Dictionary with a decorator for assigning functions to keys."""
def
set
(
self
,
key
):
def
set
(
self
,
key
):
"""
"""
Decorator function to set the given key to
Decorator function to set the given key to
the decorated function.
the decorated function.
>>> modifiers = {}
>>> modifiers = {}
>>> @modifiers.set('P')
>>> @modifiers.set('P')
... def render_tongue(self, tag_name=None, context=None):
... def render_tongue(self, tag_name=None, context=None):
... return ":P
%
s"
%
tag_name
... return ":P
%
s"
%
tag_name
>>> modifiers
>>> modifiers
{'P': <function render_tongue at 0x...>}
{'P': <function render_tongue at 0x...>}
"""
"""
def
setter
(
func
):
def
setter
(
func
):
...
@@ -35,18 +36,17 @@ class Modifiers(dict):
...
@@ -35,18 +36,17 @@ class Modifiers(dict):
return
setter
return
setter
class
Template
(
object
):
class
Template
(
object
):
tag_re
=
None
tag_re
=
None
otag
=
'{{'
otag
=
'{{'
ctag
=
'}}'
ctag
=
'}}'
modifiers
=
Modifiers
()
modifiers
=
Modifiers
()
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
from
view
import
View
from
.
view
import
View
self
.
template
=
template
self
.
template
=
template
...
@@ -56,6 +56,7 @@ class Template(object):
...
@@ -56,6 +56,7 @@ class Template(object):
self
.
view
=
context
if
isinstance
(
context
,
View
)
else
View
(
context
=
context
)
self
.
view
=
context
if
isinstance
(
context
,
View
)
else
View
(
context
=
context
)
self
.
_compile_regexps
()
self
.
_compile_regexps
()
def
_compile_regexps
(
self
):
def
_compile_regexps
(
self
):
tags
=
{
tags
=
{
'otag'
:
re
.
escape
(
self
.
otag
),
'otag'
:
re
.
escape
(
self
.
otag
),
...
@@ -68,6 +69,7 @@ class Template(object):
...
@@ -68,6 +69,7 @@ class Template(object):
tag
=
r"
%(otag)
s(#|=|&|!|>|\{)?(.+?)\1?
%(ctag)
s+"
tag
=
r"
%(otag)
s(#|=|&|!|>|\{)?(.+?)\1?
%(ctag)
s+"
self
.
tag_re
=
re
.
compile
(
tag
%
tags
)
self
.
tag_re
=
re
.
compile
(
tag
%
tags
)
def
_render_sections
(
self
,
template
,
view
):
def
_render_sections
(
self
,
template
,
view
):
while
True
:
while
True
:
match
=
self
.
section_re
.
search
(
template
)
match
=
self
.
section_re
.
search
(
template
)
...
@@ -82,18 +84,22 @@ class Template(object):
...
@@ -82,18 +84,22 @@ class Template(object):
# Callable
# Callable
if
it
and
isinstance
(
it
,
collections
.
Callable
):
if
it
and
isinstance
(
it
,
collections
.
Callable
):
replacer
=
it
(
inner
)
replacer
=
it
(
inner
)
# Dictionary
# Dictionary
elif
it
and
hasattr
(
it
,
'keys'
)
and
hasattr
(
it
,
'__getitem__'
):
elif
it
and
hasattr
(
it
,
'keys'
)
and
hasattr
(
it
,
'__getitem__'
):
if
section
[
2
]
!=
'^'
:
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
# Lists
# Lists
elif
it
and
hasattr
(
it
,
'__iter__'
):
elif
it
and
hasattr
(
it
,
'__iter__'
):
if
section
[
2
]
!=
'^'
:
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_list
(
inner
,
it
)
replacer
=
self
.
_render_list
(
inner
,
it
)
# Other objects
# Other objects
elif
it
and
isinstance
(
it
,
object
):
elif
it
and
isinstance
(
it
,
object
):
if
section
[
2
]
!=
'^'
:
if
section
[
2
]
!=
'^'
:
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
# Falsey and Negated or Truthy and Not Negated
# Falsey and Negated or Truthy and Not Negated
elif
(
not
it
and
section
[
2
]
==
'^'
)
or
(
it
and
section
[
2
]
!=
'^'
):
elif
(
not
it
and
section
[
2
]
==
'^'
)
or
(
it
and
section
[
2
]
!=
'^'
):
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
replacer
=
self
.
_render_dictionary
(
inner
,
it
)
...
@@ -102,6 +108,7 @@ class Template(object):
...
@@ -102,6 +108,7 @@ class Template(object):
return
template
return
template
def
_render_tags
(
self
,
template
):
def
_render_tags
(
self
,
template
):
while
True
:
while
True
:
match
=
self
.
tag_re
.
search
(
template
)
match
=
self
.
tag_re
.
search
(
template
)
...
@@ -116,22 +123,32 @@ class Template(object):
...
@@ -116,22 +123,32 @@ class Template(object):
return
template
return
template
def
_render_dictionary
(
self
,
template
,
context
):
def
_render_dictionary
(
self
,
template
,
context
):
self
.
view
.
context_list
.
insert
(
0
,
context
)
self
.
view
.
context_list
.
insert
(
0
,
context
)
template
=
Template
(
template
,
self
.
view
)
template
=
Template
(
template
,
self
.
view
)
out
=
template
.
render
()
out
=
template
.
render
()
self
.
view
.
context_list
.
pop
(
0
)
self
.
view
.
context_list
.
pop
(
0
)
return
out
return
out
def
_render_list
(
self
,
template
,
listing
):
def
_render_list
(
self
,
template
,
listing
):
insides
=
[]
insides
=
[]
for
item
in
listing
:
for
item
in
listing
:
insides
.
append
(
self
.
_render_dictionary
(
template
,
item
))
insides
.
append
(
self
.
_render_dictionary
(
template
,
item
))
return
''
.
join
(
insides
)
return
''
.
join
(
insides
)
@modifiers.set
(
None
)
@modifiers.set
(
None
)
def
_render_tag
(
self
,
tag_name
):
def
_render_tag
(
self
,
tag_name
):
raw
=
self
.
view
.
get
(
tag_name
,
''
)
raw
=
self
.
view
.
get
(
tag_name
,
''
)
# For methods with no return value
# For methods with no return value
...
@@ -143,30 +160,41 @@ class Template(object):
...
@@ -143,30 +160,41 @@ class Template(object):
return
escape
(
raw
)
return
escape
(
raw
)
@modifiers.set
(
'!'
)
@modifiers.set
(
'!'
)
def
_render_comment
(
self
,
tag_name
):
def
_render_comment
(
self
,
tag_name
):
return
''
return
''
@modifiers.set
(
'>'
)
@modifiers.set
(
'>'
)
def
_render_partial
(
self
,
template_name
):
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
)
template
=
Template
(
markup
,
self
.
view
)
return
template
.
render
()
return
template
.
render
()
@modifiers.set
(
'='
)
@modifiers.set
(
'='
)
def
_change_delimiter
(
self
,
tag_name
):
def
_change_delimiter
(
self
,
tag_name
):
"""Changes the Mustache delimiter."""
"""Changes the Mustache delimiter."""
self
.
otag
,
self
.
ctag
=
tag_name
.
split
(
' '
)
self
.
otag
,
self
.
ctag
=
tag_name
.
split
(
' '
)
self
.
_compile_regexps
()
self
.
_compile_regexps
()
return
''
return
''
@modifiers.set
(
'{'
)
@modifiers.set
(
'{'
)
@modifiers.set
(
'&'
)
@modifiers.set
(
'&'
)
def
render_unescaped
(
self
,
tag_name
):
def
render_unescaped
(
self
,
tag_name
):
"""Render a tag without escaping it."""
"""Render a tag without escaping it."""
return
literal
(
self
.
view
.
get
(
tag_name
,
''
))
return
literal
(
self
.
view
.
get
(
tag_name
,
''
))
def
render
(
self
,
encoding
=
None
):
def
render
(
self
,
encoding
=
None
):
template
=
self
.
_render_sections
(
self
.
template
,
self
.
view
)
template
=
self
.
_render_sections
(
self
.
template
,
self
.
view
)
result
=
self
.
_render_tags
(
template
)
result
=
self
.
_render_tags
(
template
)
...
...
pystache/view.py
View file @
20bec630
from
pystache
import
Template
# -*- coding: utf-8 -*-
import
os.path
"""
pystache.loader
~~~~~~~~~~~~~~~
This module provides Pystache's views.
"""
import
re
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
):
class
View
(
object
):
"""A Pystache view."""
template_name
=
None
template_name
=
None
template_path
=
None
template_path
=
None
template
=
None
template
=
None
template_encoding
=
None
template_encoding
=
None
template_extension
=
'mustache'
template_extension
=
'mustache'
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
def
__init__
(
self
,
template
=
None
,
context
=
None
,
**
kwargs
):
self
.
template
=
template
self
.
template
=
template
context
=
context
or
{}
context
=
context
or
{}
context
.
update
(
**
kwargs
)
context
.
update
(
kwargs
)
self
.
context_list
=
[
context
]
self
.
context_list
=
[
context
]
def
get
(
self
,
attr
,
default
=
None
):
def
get
(
self
,
attr
,
default
=
None
):
attr
=
get_or_attr
(
self
.
context_list
,
attr
,
getattr
(
self
,
attr
,
default
))
attr
=
get_or_attr
(
self
.
context_list
,
attr
,
getattr
(
self
,
attr
,
default
))
if
hasattr
(
attr
,
'__call__'
)
and
type
(
attr
)
is
UnboundMethodType
:
if
hasattr
(
attr
,
'__call__'
)
and
type
(
attr
)
is
UnboundMethodType
:
return
attr
()
return
attr
()
else
:
else
:
return
attr
return
attr
def
get_template
(
self
,
template_name
):
def
get_template
(
self
,
template_name
):
if
not
self
.
template
:
if
not
self
.
template
:
from
pystache
import
Loader
template_name
=
self
.
_get_template_name
(
template_name
)
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
return
self
.
template
def
_get_template_name
(
self
,
template_name
=
None
):
def
_get_template_name
(
self
,
template_name
=
None
):
"""TemplatePartial => template_partial
"""TemplatePartial => template_partial
Takes a string but defaults to using the current class' name or
Takes a string but defaults to using the current class' name or
the `template_name` attribute
the `template_name` attribute
.
"""
"""
if
template_name
:
if
template_name
:
return
template_name
return
template_name
...
@@ -64,6 +75,7 @@ class View(object):
...
@@ -64,6 +75,7 @@ class View(object):
return
re
.
sub
(
'[A-Z]'
,
repl
,
template_name
)[
1
:]
return
re
.
sub
(
'[A-Z]'
,
repl
,
template_name
)[
1
:]
def
_get_context
(
self
):
def
_get_context
(
self
):
context
=
{}
context
=
{}
for
item
in
self
.
context_list
:
for
item
in
self
.
context_list
:
...
@@ -71,12 +83,16 @@ class View(object):
...
@@ -71,12 +83,16 @@ class View(object):
context
.
update
(
item
)
context
.
update
(
item
)
return
context
return
context
def
render
(
self
,
encoding
=
None
):
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
):
def
__contains__
(
self
,
needle
):
return
needle
in
self
.
context
or
hasattr
(
self
,
needle
)
return
needle
in
self
.
context
or
hasattr
(
self
,
needle
)
def
__getitem__
(
self
,
attr
):
def
__getitem__
(
self
,
attr
):
val
=
self
.
get
(
attr
,
None
)
val
=
self
.
get
(
attr
,
None
)
...
@@ -84,11 +100,36 @@ class View(object):
...
@@ -84,11 +100,36 @@ class View(object):
raise
KeyError
(
"Key '
%
s' does not exist in View"
%
attr
)
raise
KeyError
(
"Key '
%
s' does not exist in View"
%
attr
)
return
val
return
val
def
__getattr__
(
self
,
attr
):
def
__getattr__
(
self
,
attr
):
if
attr
==
'context'
:
if
attr
==
'context'
:
return
self
.
_get_context
()
return
self
.
_get_context
()
raise
AttributeError
(
"Attribute '
%
s' does not exist in View"
%
attr
)
raise
AttributeError
(
"Attribute '
%
s' does not exist in View"
%
attr
)
def
__str__
(
self
):
def
__str__
(
self
):
return
self
.
render
()
return
self
.
render
()
\ No newline at end of file
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