Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c14e755
Showing
3 changed files
with
166 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
django-linestripper | ||
==================== | ||
|
||
django-linestripper removes blank / empty / whitespaced lines generated by template tags. | ||
|
||
Compatibility: | ||
-------------- | ||
|
||
django == 1.4 | ||
|
||
Example | ||
------- | ||
|
||
### Template ### | ||
|
||
<h1>My list</h1> | ||
|
||
<ul> | ||
{% for item in items %} | ||
<li>{{ item }}</li> | ||
{% endfor %} | ||
</ul> | ||
|
||
### Rendered without django-linestripper ### | ||
|
||
<h1>My list</h1> | ||
|
||
<ul> | ||
|
||
<li>item 1</li> | ||
|
||
<li>item 2</li> | ||
|
||
<li>item 3</li> | ||
|
||
</ul> | ||
|
||
### Rendered with django-linestripper ### | ||
|
||
<h1>My list</h1> | ||
|
||
<ul> | ||
<li>item 1</li> | ||
<li>item 2</li> | ||
<li>item 3</li> | ||
</ul> | ||
|
||
Setup instructions | ||
------------------ | ||
|
||
* Put the `django_linestripper` folder at the root of your app structure | ||
* Edit `settings.py`: | ||
* In `TEMPLATE_LOADERS`, add `django_linestripper.stripper.Loader` as the **first** loader | ||
* In `MIDDLEWARE_CLASSES`, put `django_linestripper.stripper.StripperMiddleware` wherever you want | ||
* You're done ! | ||
|
||
Advanced usage | ||
-------------- | ||
|
||
Two configuration constants can be overriden in `settings.py`: | ||
|
||
### `STRIPPER_TAG` ### | ||
|
||
*defaults to `__STRIPPER_TAG__`* | ||
|
||
A unique string that you don't use in your templates. It will be suppressed by the django-linestripper middleware. | ||
|
||
### `STRIPPER_CLEAR_LINE` ### | ||
|
||
*defaults to `False`* | ||
|
||
Clear every non-generated whitespace metacharacter before `\n`. For instance: | ||
|
||
#### With `STRIPPER_CLEAR_LINE = False` #### | ||
\n\t\t\t\n | ||
=> \n\t\t\t\n | ||
|
||
#### With `STRIPPER_CLEAR_LINE = True` #### | ||
\n\t\t\t\n | ||
=> \n\n | ||
|
||
How it works | ||
------------ | ||
|
||
* Step 1: tag empty lines with `__STRIPPER_TAG__` | ||
* Step 2: wait for the rendered template | ||
* Step 3: suppress blank lines and suppress `__STRIPPER_TAG__` | ||
|
||
Notes | ||
----- | ||
|
||
This [thread](https://code.djangoproject.com/ticket/2594) on DjangoProject.com talks about the subject in a very precise manner. A patch has been submitted but the validation process is very long. Please do not hesitate in contacting me when this whitespace issue is resolved. | ||
|
||
License | ||
------- | ||
|
||
I always dreamed of doing that. | ||
|
||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | ||
Version 2, December 2004 | ||
|
||
Copyright (C) 2012 Loïs Di Qual <lois[at]di-qual.net> | ||
|
||
Everyone is permitted to copy and distribute verbatim or modified | ||
copies of this license document, and changing it is allowed as long | ||
as the name is changed. | ||
|
||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE | ||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
|
||
0. You just DO WHAT THE FUCK YOU WANT TO. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
from django.conf import settings | ||
from django.template.loaders import app_directories | ||
|
||
import re | ||
|
||
# To be set in settings.py | ||
STRIPPER_TAG = getattr(settings, 'STRIPPER_TAG', '__STRIPPER_TAG__') | ||
STRIPPER_CLEAR_LINE = getattr(settings, 'STRIPPER_CLEAR_LINE', False) | ||
|
||
# Finders | ||
FIND_BLANK_LINE = r'\n(\s*)\n' | ||
FIND_START_BLANK_LINE = r'^(\s*)\n' | ||
FIND_TAG = STRIPPER_TAG | ||
|
||
# Replacers | ||
REPLACE_WITH_TAG = r'\n'+ STRIPPER_TAG +'\n' if STRIPPER_CLEAR_LINE else r'\n\1'+ STRIPPER_TAG +'\n' | ||
REPLACE_START_WITH_TAG = STRIPPER_TAG +'\n' if STRIPPER_CLEAR_LINE else r'\n\1'+ STRIPPER_TAG +'\n' | ||
|
||
# Deleters | ||
DELETE_BLANK_LINE = r'\n' | ||
DELETE_START_BLANK_LINE = r'' | ||
DELETE_TAG = '' | ||
|
||
''' | ||
This is called AFTER the template generation. | ||
It suppresses blank lines and deletes STRIPPER_TAG | ||
''' | ||
class StripperMiddleware(object): | ||
def process_response(self, request, response): | ||
# Suppress a blank line at the beginning of the document | ||
response.content = re.sub(FIND_START_BLANK_LINE, DELETE_START_BLANK_LINE, response.content) | ||
# Suppress blank lines | ||
response.content = re.sub(FIND_BLANK_LINE, DELETE_BLANK_LINE, response.content) | ||
# Delete STRIPPER_TAG | ||
response.content = re.sub(FIND_TAG, DELETE_TAG, response.content) | ||
return response | ||
|
||
def process_request(self, request): | ||
pass | ||
|
||
''' | ||
This is called BEFORE the template generation. | ||
It replaces blank lines by STRIPPER_TAG | ||
''' | ||
class Loader(app_directories.Loader): | ||
is_usable = True | ||
|
||
def process_content(self, content): | ||
content = re.sub(FIND_BLANK_LINE, REPLACE_WITH_TAG, content) | ||
content = re.sub(FIND_START_BLANK_LINE, REPLACE_WITH_TAG, content) | ||
return content | ||
|
||
def load_template(self, template_name, template_dirs=None): | ||
source, origin = self.load_template_source(template_name, template_dirs) | ||
return self.process_content(source), origin |