Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Include at bottom #43

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions bowerstatic/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,19 @@ def __init__(self, publisher_signature='bowerstatic', autoversion=None):
self._renderer = Renderer()
self.autoversion = autoversion or filesystem_second_autoversion

def components(self, name, path):
def components(self, name, path, bottom=False):
if name in self._component_collections:
raise Error("Duplicate name for components directory: %s" % name)
result = ComponentCollection(self, name, path=path)
result = ComponentCollection(self, name, path=path, bottom=bottom)
self._component_collections[name] = result
return result

def local_components(self, name, component_collection):
def local_components(self, name, component_collection, bottom=False):
if name in self._component_collections:
raise Error("Duplicate name for local components: %s" % name)
result = ComponentCollection(self, name,
fallback_collection=component_collection)
fallback_collection=component_collection,
bottom=bottom)
self._component_collections[name] = result
return result

Expand Down Expand Up @@ -63,12 +64,13 @@ def get_filename(self, bower_components_name,


class ComponentCollection(object):
def __init__(self, bower, name, path=None, fallback_collection=None):
def __init__(self, bower, name, path=None, fallback_collection=None, bottom=False):
self.bower = bower
self.name = name
self._resources = {}
self.path = path
self.fallback_collection = fallback_collection
self.bottom = bottom
if path is not None:
self._components = self.load_components(path)
else:
Expand Down Expand Up @@ -267,6 +269,10 @@ def url(self):
def renderer(self, resource):
return self.bower.renderer(resource)

@property
def bottom(self):
return self.component_collection.bottom


class Resource(object):
def __init__(self, component, file_path, dependencies):
Expand All @@ -290,3 +296,7 @@ def content(self):

def renderer(self):
return self.component.renderer(self)

@property
def bottom(self):
return self.file_path.endswith('.js') and self.component.bottom
11 changes: 9 additions & 2 deletions bowerstatic/includer.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,13 @@ def __init__(self):
def add(self, inclusion):
self._inclusions.append(inclusion)

def render(self):
def render(self, bottom=False):
inclusions = topological_sort(
self._inclusions, lambda inclusion: inclusion.dependencies())
snippets = [inclusion.html() for inclusion in inclusions]
snippets = [inclusion.html() for inclusion in inclusions
if (not bottom and not inclusion.bottom)
or (bottom and inclusion.bottom)
]
return '\n'.join(snippets)


Expand Down Expand Up @@ -71,3 +74,7 @@ def dependencies(self):

def html(self):
return self.renderer(self.resource)

@property
def bottom(self):
return self.resource.bottom
4 changes: 3 additions & 1 deletion bowerstatic/injector.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ def __call__(self, request):
body = response.body
response.body = b''
body = body.replace(
b'</head>', b''.join((inclusions.render().encode(), b'</head>')))
b'</head>', b''.join((inclusions.render(bottom=False).encode(), b'</head>')))
body = body.replace(
b'</body>', b''.join((inclusions.render(bottom=True).encode(), b'</body>')))
response.write(body)
return response

Expand Down
35 changes: 35 additions & 0 deletions bowerstatic/tests/test_injector.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,41 @@ def wsgi(environ, start_response):
b'</head><body>Hello!</body></html>')


def test_injector_bottom():
bower = bowerstatic.Bower()

components = bower.components('components', os.path.join(
os.path.dirname(__file__), 'bower_components'), bottom=True)

def wsgi(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=UTF-8')])
include = components.includer(environ)
# going to pull in jquery-ui and jquery twice
include('jquery-ui')
include('jquery-ui-bootstrap')
return [b'<html><head></head><body>Hello!</body></html>']

injector = bower.injector(wsgi)

c = Client(injector)

response = c.get('/')

assert response.body == (
b'<html><head>'
b'<link rel="stylesheet" type="text/css" '
b'href="/bowerstatic/components/jquery-ui-bootstrap/0.2.5/'
b'jquery.ui.theme.css">'
b'</head><body>Hello!'
b'<script type="text/javascript" '
b'src="/bowerstatic/components/jquery/2.1.1/dist/jquery.js">'
b'</script>\n'
b'<script type="text/javascript" '
b'src="/bowerstatic/components/jquery-ui/1.10.4/ui/jquery-ui.js">'
b'</script>'
b'</body></html>'
)

def test_injector_no_head_to_inject():
bower = bowerstatic.Bower()

Expand Down
15 changes: 15 additions & 0 deletions doc/integrating.rst
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,21 @@ or::
include('static/favicon.ico', lambda resource: '<link rel="shortcut icon" type="image/x-icon" href="' + resource.url + '"/>')



Including at the bottom
-----------------------

For javascripts, it will sometimes be better to include the script at the bottom. To include all `*.js` files
of a component at the bottom, you have to add `bottom=True` when loading components::

components = bower.components('components', '/path/to/bower_components',
bottom=True)

Local components do have the same parameter::

local = bower.local_components('local', components, bottom=True)


URL structure
-------------

Expand Down