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
7492f81a
Commit
7492f81a
authored
Dec 28, 2011
by
Chris Jerdonek
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored Renderer._make_context() to use a Context.create() method.
parent
c9cb0c53
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
27 deletions
+141
-27
pystache/context.py
+66
-0
pystache/renderer.py
+13
-26
tests/test_context.py
+62
-1
No files found.
pystache/context.py
View file @
7492f81a
...
@@ -67,6 +67,11 @@ class Context(object):
...
@@ -67,6 +67,11 @@ class Context(object):
Querying the stack for the value of a key queries the items in the
Querying the stack for the value of a key queries the items in the
stack in order from last-added objects to first (last in, first out).
stack in order from last-added objects to first (last in, first out).
*Caution*:
This class currently does not support recursive nesting in that
items in the stack cannot themselves be Context instances.
See the docstrings of the methods of this class for more information.
See the docstrings of the methods of this class for more information.
"""
"""
...
@@ -99,9 +104,70 @@ class Context(object):
...
@@ -99,9 +104,70 @@ class Context(object):
In particular, an item can be an ordinary object with no
In particular, an item can be an ordinary object with no
mapping-like characteristics.
mapping-like characteristics.
*Caution*:
Items should not themselves be Context instances, as recursive
nesting does not behave as one might expect.
"""
"""
self
.
_stack
=
list
(
items
)
self
.
_stack
=
list
(
items
)
@staticmethod
def
create
(
*
context
,
**
kwargs
):
"""
Build a Context instance from a sequence of "mapping-like" objects.
This factory-style method is more general than the Context class's
constructor in that Context instances can themselves appear in the
argument list. This is not true of the constructor.
Here is an example illustrating various aspects of this method:
>>> obj1 = {'animal': 'cat', 'vegetable': 'carrot', 'mineral': 'copper'}
>>> obj2 = Context({'vegetable': 'spinach', 'mineral': 'silver'})
>>>
>>> context = Context.create(obj1, None, obj2, mineral='gold')
>>>
>>> context.get('animal')
'cat'
>>> context.get('vegetable')
'spinach'
>>> context.get('mineral')
'gold'
Arguments:
*context: zero or more dictionaries, Context instances, or objects
with which to populate the initial context stack. None
arguments will be skipped. Items in the *context list are
added to the stack in order so that later items in the argument
list take precedence over earlier items. This behavior is the
same as the constructor's.
**kwargs: additional key-value data to add to the context stack.
As these arguments appear after all items in the *context list,
in the case of key conflicts these values take precedence over
all items in the *context list. This behavior is the same as
the constructor's.
"""
items
=
context
context
=
Context
()
for
item
in
items
:
if
item
is
None
:
continue
if
isinstance
(
item
,
Context
):
context
.
_stack
.
extend
(
item
.
_stack
)
else
:
context
.
push
(
item
)
if
kwargs
:
context
.
push
(
kwargs
)
return
context
def
get
(
self
,
key
,
default
=
None
):
def
get
(
self
,
key
,
default
=
None
):
"""
"""
Query the stack for the given key, and return the resulting value.
Query the stack for the given key, and return the resulting value.
...
...
pystache/renderer.py
View file @
7492f81a
...
@@ -167,24 +167,6 @@ class Renderer(object):
...
@@ -167,24 +167,6 @@ class Renderer(object):
# the default_encoding and decode_errors attributes.
# the default_encoding and decode_errors attributes.
return
unicode
(
s
,
self
.
default_encoding
,
self
.
decode_errors
)
return
unicode
(
s
,
self
.
default_encoding
,
self
.
decode_errors
)
def
_make_context
(
self
,
context
,
**
kwargs
):
"""
Initialize the context attribute.
"""
if
context
is
None
:
context
=
{}
if
isinstance
(
context
,
Context
):
context
=
context
.
copy
()
else
:
context
=
Context
(
context
)
if
kwargs
:
context
.
push
(
kwargs
)
return
context
def
_make_reader
(
self
):
def
_make_reader
(
self
):
"""
"""
Create a Reader instance using current attributes.
Create a Reader instance using current attributes.
...
@@ -262,7 +244,7 @@ class Renderer(object):
...
@@ -262,7 +244,7 @@ class Renderer(object):
loader
=
self
.
_make_loader
()
loader
=
self
.
_make_loader
()
return
loader
.
get
(
template_name
)
return
loader
.
get
(
template_name
)
def
render_path
(
self
,
template_path
,
context
=
None
,
**
kwargs
):
def
render_path
(
self
,
template_path
,
*
context
,
**
kwargs
):
"""
"""
Render the template at the given path using the given context.
Render the template at the given path using the given context.
...
@@ -270,9 +252,9 @@ class Renderer(object):
...
@@ -270,9 +252,9 @@ class Renderer(object):
"""
"""
template
=
self
.
read
(
template_path
)
template
=
self
.
read
(
template_path
)
return
self
.
render
(
template
,
context
,
**
kwargs
)
return
self
.
render
(
template
,
*
context
,
**
kwargs
)
def
render
(
self
,
template
,
context
=
None
,
**
kwargs
):
def
render
(
self
,
template
,
*
context
,
**
kwargs
):
"""
"""
Render the given template using the given context.
Render the given template using the given context.
...
@@ -285,15 +267,20 @@ class Renderer(object):
...
@@ -285,15 +267,20 @@ class Renderer(object):
using this instance's default_encoding and decode_errors
using this instance's default_encoding and decode_errors
attributes. See the constructor docstring for more information.
attributes. See the constructor docstring for more information.
context: a dictionary, Context, or object (e.g. a View instance).
*context: zero or more dictionaries, Context instances, or objects
with which to populate the initial context stack. None
arguments are skipped. Items in the *context list are added to
the context stack in order so that later items in the argument
list take precedence over earlier items.
**kwargs: additional key values to add to the context when
**kwargs: additional key-value data to add to the context stack.
rendering. These values take precedence over the context on
As these arguments appear after all items in the *context list,
any key conflicts.
in the case of key conflicts these values take precedence over
all items in the *context list.
"""
"""
engine
=
self
.
_make_render_engine
()
engine
=
self
.
_make_render_engine
()
context
=
self
.
_make_context
(
context
,
**
kwargs
)
context
=
Context
.
create
(
*
context
,
**
kwargs
)
# RenderEngine.render() requires that the template string be unicode.
# RenderEngine.render() requires that the template string be unicode.
template
=
self
.
_to_unicode_hard
(
template
)
template
=
self
.
_to_unicode_hard
(
template
)
...
...
tests/test_context.py
View file @
7492f81a
...
@@ -168,7 +168,7 @@ class GetItemTestCase(TestCase):
...
@@ -168,7 +168,7 @@ class GetItemTestCase(TestCase):
self
.
assertRaises
(
AttributeError
,
_get_item
,
obj
,
"foo"
)
self
.
assertRaises
(
AttributeError
,
_get_item
,
obj
,
"foo"
)
class
ContextTest
Case
(
TestCase
):
class
ContextTest
s
(
TestCase
):
"""
"""
Test the Context class.
Test the Context class.
...
@@ -189,6 +189,67 @@ class ContextTestCase(TestCase):
...
@@ -189,6 +189,67 @@ class ContextTestCase(TestCase):
"""
"""
context
=
Context
({},
{},
{})
context
=
Context
({},
{},
{})
## Test the static create() method.
def
test_create__dictionary
(
self
):
"""
Test passing a dictionary.
"""
context
=
Context
.
create
({
'foo'
:
'bar'
})
self
.
assertEquals
(
context
.
get
(
'foo'
),
'bar'
)
def
test_create__none
(
self
):
"""
Test passing None.
"""
context
=
Context
.
create
({
'foo'
:
'bar'
},
None
)
self
.
assertEquals
(
context
.
get
(
'foo'
),
'bar'
)
def
test_create__object
(
self
):
"""
Test passing an object.
"""
class
Foo
(
object
):
foo
=
'bar'
context
=
Context
.
create
(
Foo
())
self
.
assertEquals
(
context
.
get
(
'foo'
),
'bar'
)
def
test_create__context
(
self
):
"""
Test passing a Context instance.
"""
obj
=
Context
({
'foo'
:
'bar'
})
context
=
Context
.
create
(
obj
)
self
.
assertEquals
(
context
.
get
(
'foo'
),
'bar'
)
def
test_create__kwarg
(
self
):
"""
Test passing a keyword argument.
"""
context
=
Context
.
create
(
foo
=
'bar'
)
self
.
assertEquals
(
context
.
get
(
'foo'
),
'bar'
)
def
test_create__precedence_positional
(
self
):
"""
Test precedence of positional arguments.
"""
context
=
Context
.
create
({
'foo'
:
'bar'
},
{
'foo'
:
'buzz'
})
self
.
assertEquals
(
context
.
get
(
'foo'
),
'buzz'
)
def
test_create__precedence_keyword
(
self
):
"""
Test precedence of keyword arguments.
"""
context
=
Context
.
create
({
'foo'
:
'bar'
},
foo
=
'buzz'
)
self
.
assertEquals
(
context
.
get
(
'foo'
),
'buzz'
)
def
test_get__key_present
(
self
):
def
test_get__key_present
(
self
):
"""
"""
Test getting a key.
Test getting a key.
...
...
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