Serve: option to store html files on disk

I’m using TailwindCSS as a CSS framework. It generates CSS classes definitions from the CSS classes present in the HTML.

If I configure TailwindCSS to look after the templates folder, it works fine. I use tailwindcss --watch, which generated its CSS to the static folder, and zola serve, which put assets in the public folder.

But when the CSS class names are dynamically generated by Zola macros, they’re not present in the templates folder: only in the public folder, where generated HTML files live.

Problem is: only zola build actually write those files, zola serve store them in-memory, thus making them inaccessible to tailwindcss. It would be super useful to store to have an option like --store-html to the serve subcommand for those kinds of workflows.

I wrote a patch that I’m already using :smiley:

Hi again @keats!

This feature may be useful to people using various CSS frameworks and have a place upstream imho.

Can I open a PR? Thanks.

I use tailwind and it works well with zola. sometimes but not always a build is needed as you suggest.

Two terminals are needed

% zola serve 
% npx tailwindcss -i ./static/tailwind_input.css -o ./static/tailwind.css  --watch

It took some tinkering to figure out the tailwind.config.
The following examines/process .html files in templates and .md markdown files in content dir. And the transform section preprocess or prioritize markdown that might contain html or css with tailwind classes.

module.exports = {
  
  content: [
    "./templates/**/*.{html,js}",
    "./content/**/*.md"
    ],

  transform: {
    md: (content) => {
      return remark().process(content)
    }
  },

I agree it’s not always needed, and came with a conf close to yours!

However, when generating tailwind class names with Tera macros, the classes can’t be seen in the templates/, but only in the public/ folder. See for example this code:

{% macro triangle_title(text, level=2, left=true, size=40, color="#a83b51", textsize="7xl", classes="", id="") %}
{%- set width = size * 1.5 | round -%}
{%- set width = width ~ "" | replace(from=".0", to="") -%}
{%- set demiheight = size / 1.6 | round -%}
{%- set demiheight = demiheight ~ "" | replace(from=".0", to="") -%}
{%- if left -%}
  {%- set side = "left" -%}
  {%- set s = "l" -%}
  {%- set S = "r" -%}
  {%- set pseudo = "before" -%}
{%- else -%}
  {%- set side = "right" -%}
  {%- set s = "r" -%}
  {%- set S = "l" -%}
  {%- set pseudo = "after" -%}
{%- endif -%}
{%- if id == "" -%}
  {%- set id = text | slugify -%}
{%- endif -%}

<h{{level}} id="{{id}}" class="{{classes}} text-{{textsize}} flex items-center
  font-title font-black text-green-tone-2
  {{pseudo}}:m{{S}}-8
  {{pseudo}}:inline-block {{pseudo}}:w-0 {{pseudo}}:h-0
  {{pseudo}}:border-y-[{{size}}px] {{pseudo}}:border-{{s}}-[{{width}}px]
  {{pseudo}}:border-y-transparent  {{pseudo}}:border-{{s}}-[{{color}}]">
	{{ text }}
</h{{level}}>
{% endmacro %}

Which generate for example this somewhere in the public/ folder:

<h2 id="title" class="italic text-lg flex items-center
font-title font-black text-green-tone-2
before:ml-8
before:inline-block before:w-0 before:h-0
before:border-y-[70px] before:border-l-[70px]
before:border-y-transparent  before:border-l-[red]">
	The text
</h2>
"

Here tailwind needs the output to generate all the classes.
That’s the kind of workflow that really needs zola serve to write the HTML to disk.

Oh you are using variables… If they are limited in number then use safelist

  safelist: [
    'bg-red-500',
    'text-3xl',
    'lg:text-4xl',
  ]

Otherwise you gotta do a zola build

In response to that hellishly long class name italic text-lg flex items-center font-title font-black text-green-tone-2 before:ml-8 before:inline-block before:w-0 before:h-0 before:border-y-[70px] before:border-l-[70px] before:border-y-transparent before:border-l-[red]

read this this article on not using tailwind

And on the positive side, Daisy UI is a component library that helped me deal with tailwind.

Yeah, I’ll stick with my patch implementing zola serve --store-html to store html files just as zola build.

Thanks anyways

oh are you writing some rust. was it easy enough to extend this zola?

Yeah it has been quite easy, the Rust’s strong type model makes it quite easy to understand the code imo, though I’m not an experienced Rust dev. And Zola’s codebase is very clean. You can see my patch at the beginning of this thread! Took me ~4h, and it was my first time patching Zola.