Added a django-compressor Filter class.

This commit is contained in:
Rocky Meza
2014-02-01 21:32:00 -07:00
parent 2e832c5ad8
commit 62d19139f4
9 changed files with 109 additions and 26 deletions

View File

@@ -15,6 +15,19 @@ A collection of tools for making it easier to use PyScss within Django.
and will only use staticfiles_storage to find the file.
Using in conjunction with django-compressor.
============================================
django-pyscss comes with support for django-compressor. All you have to do is
add it to your ``COMPRESS_PRECOMPILERS`` setting. ::
COMPRESS_PRECOMPILERS = (
# ...
('text/x-scss', 'django_pyscss.compressor.DjangoScssFilter'),
# ...
)
Running the tests
=================

View File

@@ -0,0 +1,21 @@
from __future__ import absolute_import
import os
from compressor.filters import FilterBase
from django_pyscss.scss import DjangoScss, config
class DjangoScssFilter(FilterBase):
compiler = DjangoScss()
def __init__(self, content, attrs=None, filter_type=None, filename=None):
# It looks like there is a bug in django-compressor because it expects
# us to accept attrs.
super(DjangoScssFilter, self).__init__(content, filter_type, filename)
def input(self, **kwargs):
if not os.path.exists(config.ASSETS_ROOT):
os.makedirs(config.ASSETS_ROOT)
return self.compiler.compile(self.content)

View File

@@ -1,33 +1,25 @@
from __future__ import absolute_import, unicode_literals
import os
import fnmatch
from django.contrib.staticfiles import finders
from django.contrib.staticfiles.storage import staticfiles_storage
from django.conf import settings
from scss import (
Scss, dequote, log, SourceFile, SassRule,
Scss, dequote, log, SourceFile, SassRule, config,
)
def find_all_files(glob):
"""
Finds all files in the django finders for a given glob,
returns the file path, if available, and the django storage object.
storage objects must implement the File storage API:
https://docs.djangoproject.com/en/dev/ref/files/storage/
"""
for finder in finders.get_finders():
for path, storage in finder.list([]):
if fnmatch.fnmatchcase(path, glob):
yield path, storage
from django_pyscss.utils import find_one_file
def find_one_file(path):
for file in find_all_files(path):
return file
# This is where PyScss is supposed to find the image files for making sprites.
config.STATIC_ROOT = find_one_file
config.STATIC_URL = staticfiles_storage.url('scss/')
# This is where PyScss places the sprite files.
config.ASSETS_ROOT = os.path.join(settings.STATIC_ROOT, 'scss', 'assets')
# PyScss expects a trailing slash.
config.ASSETS_URL = staticfiles_storage.url('scss/assets/')
class DjangoScss(Scss):

21
django_pyscss/utils.py Normal file
View File

@@ -0,0 +1,21 @@
import fnmatch
from django.contrib.staticfiles import finders
def find_all_files(glob):
"""
Finds all files in the django finders for a given glob,
returns the file path, if available, and the django storage object.
storage objects must implement the File storage API:
https://docs.djangoproject.com/en/dev/ref/files/storage/
"""
for finder in finders.get_finders():
for path, storage in finder.list([]):
if fnmatch.fnmatchcase(path, glob):
yield path, storage
def find_one_file(path):
for file in find_all_files(path):
return file

View File

@@ -16,6 +16,9 @@ install_requires = [
'Django>=1.3',
'PyScss>=1.2.0',
]
tests_require = [
'django-compressor>=1.3',
]
version = (0, 0, 1, 'final')
@@ -37,6 +40,7 @@ setup(
long_description=read('README.rst'),
packages=[package for package in find_packages() if package.startswith('django_pyscss')],
install_requires=install_requires,
tests_require=tests_require,
zip_safe=False,
include_package_data=True,
test_suite='testproject.runtests.runtests',

View File

@@ -37,6 +37,8 @@ INSTALLED_APPS = (
'django.contrib.messages',
'django.contrib.staticfiles',
'compressor',
'testproject.testapp1',
'testproject.testapp2',
)
@@ -88,3 +90,15 @@ STATIC_ROOT = os.path.join(BASE_DIR, '..', 'tmp', 'static')
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'testproject', 'static'),
)
# It doesn't seem like django-compressor respects override_settings
COMPRESS_ENABLED = True
COMPRESS_PRECOMPILERS = (
('text/x-scss', 'django_pyscss.compressor.DjangoScssFilter'),
)
STATICFILES_FINDERS = (
'compressor.finders.CompressorFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

16
tests/test_compressor.py Normal file
View File

@@ -0,0 +1,16 @@
from django.test import TestCase
from django.template.loader import Template, Context
APP2_LINK_TAG = """
{% load staticfiles compress %}
{% compress css %}
<link rel="stylesheet" type="text/x-scss" href="{% static 'css/app2.scss' %}">
{% endcompress %}
"""
class CompressorTest(TestCase):
def test_compressor_can_compile_scss(self):
actual = Template(APP2_LINK_TAG).render(Context())
self.assertIn('4b368862ec8c.css', actual)

View File

@@ -6,6 +6,8 @@ from django.conf import settings
from django_pyscss.scss import DjangoScss
from tests.utils import clean_css
compiler = DjangoScss(scss_opts={
# No compress so that I can compare more easily
@@ -40,14 +42,6 @@ IMPORT_APP2 = """
APP2_CONTENTS = FOO_CONTENTS + APP1_CONTENTS
def clean_css(string):
# The output of the compiled CSS doesn't have a newline between the ; and
# the } for some reason.
return string.strip() \
.replace('\n', '') \
.replace('; ', ';')
class ImportTestMixin(object):
def test_import_from_staticfiles_dirs(self):
actual = compile_string(IMPORT_FOO)

8
tests/utils.py Normal file
View File

@@ -0,0 +1,8 @@
def clean_css(string):
# The output of the compiled CSS doesn't have a newline between the ; and
# the } for some reason.
return string.strip() \
.replace('\n', '') \
.replace('; ', ';')