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

Allow bundles to be rendered after "theme" and "custom" bundles. #4054

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions Products/CMFPlone/resources/browser/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ def update(self):
# collect names
js_names = [name for name, rec in records.items() if rec.jscompilation]
css_names = [name for name, rec in records.items() if rec.csscompilation]
# Allow bundles to have "theme" resp. "theme" and "custom" as dependency
# so that bundles can be rendered after theme and custom resources.
js_names += ["theme"]
css_names += ["theme", "custom"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


all_names = [
name
for name, rec in records.items()
Expand Down
69 changes: 69 additions & 0 deletions Products/CMFPlone/tests/testResourceRegistries.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,34 @@ def test_bundle_depends(self):
results = view.render()
self.assertIn("http://foo.bar/foobar.js", results)

def test_bundle_depends_theme(self):
from lxml import etree

# Bluntly set a JavaScript file for the theme to ensure the "theme"
# dependency exists.
from plone.app.theming.utils import theming_policy
theme = theming_policy(self.layer["request"]).get_theme()
theme.production_js = "theme.js"

bundle = self._make_test_bundle()

# This bundle should depend on "theme"
bundle.depends = "theme"

view = ScriptsView(self.app, self.app.REQUEST, None, None)
view.update()
results = view.render()

parser = etree.HTMLParser()
parsed = etree.fromstring(results, parser)
scripts = parsed.xpath("//script")

# The last element is our script bundle depending on "theme"
self.assertEqual("http://foo.bar/foobar.js", scripts[-1].attrib["src"])

# The second last element is the theme javascript itself.
self.assertIn("theme.js", scripts[-2].attrib["src"])

def test_bundle_depends_on_multiple(self):
bundle = self._make_test_bundle()
bundle.depends = "plone,eventedit"
Expand Down Expand Up @@ -208,6 +236,19 @@ def test_resource_bogus(self):
)

class TestStylesViewlet(PloneTestCase.PloneTestCase):
def _make_test_bundle(self):
registry = getUtility(IRegistry)

bundles = registry.collectionOfInterface(
IBundleRegistry, prefix="plone.bundles"
)
bundle = bundles.add("foobar")
bundle.name = "foobar"
bundle.jscompilation = "http://foo.bar/foobar.js"
bundle.csscompilation = "http://foo.bar/foobar.css"
bundle.resources = ["foobar"]
return bundle

def test_styles_viewlet(self):
styles = StylesView(self.layer["portal"], self.layer["request"], None)
styles.update()
Expand Down Expand Up @@ -314,6 +355,34 @@ def test_remove_bundle_on_request_with_subrequest(self):
result = scripts.render()
self.assertNotIn("http://test.foo/test.min.js", result)

def test_bundle_depends_theme(self):
from lxml import etree

# Bluntly set a JavaScript file for the theme to ensure the "theme"
# dependency exists.
from plone.app.theming.utils import theming_policy
theme = theming_policy(self.layer["request"]).get_theme()
theme.production_css = "theme.css"

bundle = self._make_test_bundle()

# This bundle should depend on "theme"
bundle.depends = "theme"

view = StylesView(self.app, self.app.REQUEST, None, None)
view.update()
results = view.render()

parser = etree.HTMLParser()
parsed = etree.fromstring(results, parser)
styles = parsed.xpath("//link")

# The last element is our script bundle depending on "theme"
self.assertEqual("http://foo.bar/foobar.css", styles[-1].attrib["href"])

# The second last element is the theme javascript itself.
self.assertIn("theme.css", styles[-2].attrib["href"])


class TestExpressions(PloneTestCase.PloneTestCase):
def logout(self):
Expand Down
11 changes: 11 additions & 0 deletions news/4054.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Allow bundles to be rendered after "theme" and "custom" bundles.

Bundles can now depend on the automatically added "theme" and "custom" bundles
from plone.app.theming and be rendered after those (e.g. after the
plonetheme.barceloneta CSS).

This allows to override a theme with custom CSS from a bundle instead of having
to add the CSS customizations to the registry via the "custom_css" settings.
As a consequence, theme customization can now be done in the filesystem in
ordinary CSS files instead of being bound to a time consuming workflow which
involces upgrading the registry after every change.