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

CSS for Streamfield Blocks #2490

Closed
letops opened this issue Apr 18, 2016 · 3 comments
Closed

CSS for Streamfield Blocks #2490

letops opened this issue Apr 18, 2016 · 3 comments

Comments

@letops
Copy link

letops commented Apr 18, 2016

I have been searching for this for a while and I haven't found something which works as needed.

When declaring a new StructBlock we can define a template to be used with this specific Block, this allows us to display the whole Streamfield with a simple {% for block in page.body %}, so far so good. The problem comes from the CSS required for this template, which we want to be inserted inside the of the HTML document, because we continue using compress for our CSS and JS compression and we don't want to include CSS of unrequested blocks in our requests (yes, our CSS is quite heavy, but we are working on it and yes, we do have a lot of blocks for certain pages).

I know, you could say: "But, what you are saying makes no sense, because if you create a new page and include an unused block in your Streamfield, compress would detect this as a change and will recompress the CSS everytime the users make a new request (in the worst case scenario)". And you are right, this generates inneficient compression times, with one exception: The unique pages in the site, like the Home page (and even if that was not the case, doesn't Wagtail contains its own template cache which would reference to the old CSS compressions?).

I know of the existence of the wagtail hooks, but so far this hooks apply only for the admin's CSS not for the page rendering, or have I overstepped something? This isn't such a big feature, but it could come handy if you are searching for time-optimization when defining a lot of high-complexity blocks for a single Streamfield.

@MechanisM
Copy link

MechanisM commented Apr 18, 2016

Hey @letops ! I'm dealed with django-sekizai for such purpose.
Just created needed sekizai css template blocks in base.html and then in templates for structblocks I used sekizai's "addtoblock" - works like a charm! And btw sekizai works great with django-compressor if you need this.
As example code for gallery block:

{% load wagtailimages_tags sekizai_tags %}
{% image value.bg_img original as bg %}
{% if value.menu %}{% addtoblock 'menu' %}<li><a href="/#gallery" class="scrollto">{{ value.menu }}</a></li>{% endaddtoblock %}{% endif %}
{% addtoblock 'js' %}<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.swipebox/1.4.1/js/jquery.swipebox.min.js"></script>{% endaddtoblock %}
{% addtoblock 'css' %}<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery.swipebox/1.4.1/css/swipebox.min.css">{% endaddtoblock %}
{% addtoblock 'cssi' %}#gallery{background:url('{{ bg.url }}') {{ value.bg }}}{% endaddtoblock %}
{% addtoblock 'jsi' %}$('.swipebox').swipebox();{% endaddtoblock %}
<section id="gallery" class="add-padding">
    <div class="container">
        <h2 class="big-text text-center animate fadeInUp">{{ value.name }}</h2>
        <div class="row">{% for gridimage in value.images %}{% image gridimage original as display %}{% image gridimage fill-300x300 as thumbnail %}
            <div class="col-xs-6 col-md-3">
                <a href="{{ display.url }}" rel="gallery" class="thumbnail swipebox">
                    <img src="{{ thumbnail.url }}" alt="{{ thumbnail.alt }}">
                </a>
            </div>{% endfor %}
        </div>
    </div>
</section>

Note: in jsi and cssi "i" stands for inline code block(not a linked file) and it is being compressed too.
and in base.html:
somewhere in the top

{% render_block "css" %}
<style>{% render_block "cssi" %}</style>

and somewhere on the bottom

{% render_block "js" %}
<script>{% render_block "jsi" %}</script>

In my example code, I'm also generating block's menu item via sekizai for landing page.
Somwhere inside bootstrap navbar:
<ul class="nav navbar-nav navbar-right">{% render_block "menu" %}</ul>
Code a bit outdated tho.
Django is all about reusable apps, so learn more apps and use them!

@gasman
Copy link
Collaborator

gasman commented Apr 19, 2016

@letops You're right, Wagtail's CSS/JS hooks only influence the admin backend - generally Wagtail avoids making assumptions about how your site's frontend templates work, so there are no helpers for managing frontend CSS/JS.

Having said that - Wagtail uses Django's form media class to define CSS/JS files to be associated with specific block types within the admin edit form, e.g.:

https://github.com/torchbox/wagtail/blob/dfd8a5cc2b9a1badbeb9621e58a789aef8471d72/wagtail/wagtailcore/blocks/list_block.py#L37-L39

which are then collected into a single set by the top-level block:

https://github.com/torchbox/wagtail/blob/861bd2de14ab46c0d93287964b4b6e5d8ec8b9c1/wagtail/wagtailcore/blocks/base.py#L81-L85

and you could probably do something similar for your site frontend, by defining a frontend_media property on your block classes and having a top-level function to collect them into a single set.

I don't think we want to make that a built-in Wagtail feature, though - I think it would be highly unusual for the frontend CSS/JS to be so heavy that you'd benefit from serving assets selectively based on the presence of particular blocks, rather than serving everything in one compressed file and letting the browser cache it. (It also makes it impossible to use django-compressor's offline mode.) Happy to hear other opinions though!

@gasman gasman closed this as completed Apr 19, 2016
@letops
Copy link
Author

letops commented Apr 19, 2016

First time I create an issue and I'm astonished for the time of response in which you found a solution to my problem. Thank you for everything guys.

And I believe you are right @gasman it may require generating a lot of code which wouldn't be used quite as much as it was necessary by the Wagtail users, (which would incur in time and maintenance that could be put in better use).

Thank you very much once again. @MechanisM @gasman

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants