Skip to content

fix(server): render cookware notes in web frontend - #815

Open
davidpkj wants to merge 2 commits into
cooklang:mainfrom
davidpkj:fix/cookware-note-rendering
Open

davidpkj wants to merge 2 commits into
cooklang:mainfrom
davidpkj:fix/cookware-note-rendering

Conversation

@davidpkj

Copy link
Copy Markdown

Hi, I vibe coded this change for myself and decided to share it.

What changed: Cookware now also shows the "prep" metadata. E.g. "#pot{}(big)" will render the brackets on the frontend.
Is it Tested: cargo test passed. And copilot wrote a new test.

I have barely spent any time with the source code of this project, because I don't really have time but I would like to see this feature in the server. So if there is something wrong with this, please just close the PR with a message what's wrong. Maybe I will get back to it with more effort when I have some time.

Thanks

davidpkj and others added 2 commits October 31, 2026 10:13
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
LeMyst added a commit to LeMyst/cookcli that referenced this pull request Nov 4, 2026
@LeMyst

LeMyst commented Nov 4, 2026

Copy link
Copy Markdown
Collaborator

I pushed a cargo fmt commit (d3e71c0) to fix the failing format check. Here's what the change looks like, from a recipe that puts a note on each piece of cookware (#oven{}(fan, 200°C), #bowl{}(large), …):

Before (main): the notes are dropped

Before: cookware list and steps without notes

After (this PR): the notes appear in the cookware list and in the step badges

After: cookware notes in italics in the list and the steps

Analysis and recommendations/changes made by Claude, posted on behalf of @LeMyst.

Comment thread templates/recipe.html
{% for (item_index, step_item) in step.items.iter().enumerate() %}
{% match step_item %}
{% when crate::web::templates::StepItem::Text with (text) %}{{ text }}{% when crate::web::templates::StepItem::Ingredient with { name, reference_path, reference_query } %}{% match reference_path %}{% when Some with (path) %}<a href="{{ prefix }}/recipe/{{ path }}{% if static_mode %}.html{% endif %}{{ reference_query }}" class="ingredient-badge hover:underline" title="View recipe: {{ name }}">{{ name }}</a>{% when None %}<span class="ingredient-badge">{{ name }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Cookware with (name) %}<span class="cookware-badge">{{ name }}</span>{% when crate::web::templates::StepItem::Timer with { display, seconds } %}{% match seconds %}{% when Some with (secs) %}<span class="timer-badge" data-timer data-timer-key="{{ section_index }}-{{ step.number }}-{{ item_index }}" data-seconds="{{ secs }}" data-display="{{ display }}" data-section="{% match section.name %}{% when Some with (n) %}{{ n }}{% when None %}{% endmatch %}" data-step="{{ step.number }}" role="button" tabindex="0">⏱️ {{ display }}</span>{% when None %}<span class="timer-badge">⏱️ {{ display }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Quantity with (qty) %}<span class="font-bold text-accent-text">{{ qty }}</span>{% when crate::web::templates::StepItem::LineBreak %}<br>{% endmatch %}{% endfor %}
{% when crate::web::templates::StepItem::Text with (text) %}{{ text }}{% when crate::web::templates::StepItem::Ingredient with { name, reference_path, reference_query } %}{% match reference_path %}{% when Some with (path) %}<a href="{{ prefix }}/recipe/{{ path }}{% if static_mode %}.html{% endif %}{{ reference_query }}" class="ingredient-badge hover:underline" title="View recipe: {{ name }}">{{ name }}</a>{% when None %}<span class="ingredient-badge">{{ name }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Cookware with { name, note } %}<span class="cookware-badge">{{ name }}{% match note %}{% when Some with (n) %} <span class="italic text-faint break-words" aria-label="{{ tr.t("recipe-preparation") }}: {{ n }}">({{ n }})</span>{% when None %}{% endmatch %}</span>{% when crate::web::templates::StepItem::Timer with { display, seconds } %}{% match seconds %}{% when Some with (secs) %}<span class="timer-badge" data-timer data-timer-key="{{ section_index }}-{{ step.number }}-{{ item_index }}" data-seconds="{{ secs }}" data-display="{{ display }}" data-section="{% match section.name %}{% when Some with (n) %}{{ n }}{% when None %}{% endmatch %}" data-step="{{ step.number }}" role="button" tabindex="0">⏱️ {{ display }}</span>{% when None %}<span class="timer-badge">⏱️ {{ display }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Quantity with (qty) %}<span class="font-bold text-accent-text">{{ qty }}</span>{% when crate::web::templates::StepItem::LineBreak %}<br>{% endmatch %}{% endfor %}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Small nit on the step badge: the note sits inside <span class="cookware-badge">, so it picks up the badge's styles too:

  • the dotted underline (text-decoration: underline dotted) runs under the note as well, e.g. under "(fan, 200°C)" in the screenshot above;
  • white-space: nowrap is inherited, so a long note can't wrap and break-words has no effect. With #baking tray{}(lined with parchment) on a 320px-wide phone, the page grows to 452px and scrolls sideways (main stays at 320px).

Moving the note right after the badge fixes both (checked in the browser: back to 320px):

Suggested change
{% when crate::web::templates::StepItem::Text with (text) %}{{ text }}{% when crate::web::templates::StepItem::Ingredient with { name, reference_path, reference_query } %}{% match reference_path %}{% when Some with (path) %}<a href="{{ prefix }}/recipe/{{ path }}{% if static_mode %}.html{% endif %}{{ reference_query }}" class="ingredient-badge hover:underline" title="View recipe: {{ name }}">{{ name }}</a>{% when None %}<span class="ingredient-badge">{{ name }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Cookware with { name, note } %}<span class="cookware-badge">{{ name }}{% match note %}{% when Some with (n) %} <span class="italic text-faint break-words" aria-label="{{ tr.t("recipe-preparation") }}: {{ n }}">({{ n }})</span>{% when None %}{% endmatch %}</span>{% when crate::web::templates::StepItem::Timer with { display, seconds } %}{% match seconds %}{% when Some with (secs) %}<span class="timer-badge" data-timer data-timer-key="{{ section_index }}-{{ step.number }}-{{ item_index }}" data-seconds="{{ secs }}" data-display="{{ display }}" data-section="{% match section.name %}{% when Some with (n) %}{{ n }}{% when None %}{% endmatch %}" data-step="{{ step.number }}" role="button" tabindex="0">⏱️ {{ display }}</span>{% when None %}<span class="timer-badge">⏱️ {{ display }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Quantity with (qty) %}<span class="font-bold text-accent-text">{{ qty }}</span>{% when crate::web::templates::StepItem::LineBreak %}<br>{% endmatch %}{% endfor %}
{% when crate::web::templates::StepItem::Text with (text) %}{{ text }}{% when crate::web::templates::StepItem::Ingredient with { name, reference_path, reference_query } %}{% match reference_path %}{% when Some with (path) %}<a href="{{ prefix }}/recipe/{{ path }}{% if static_mode %}.html{% endif %}{{ reference_query }}" class="ingredient-badge hover:underline" title="View recipe: {{ name }}">{{ name }}</a>{% when None %}<span class="ingredient-badge">{{ name }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Cookware with { name, note } %}<span class="cookware-badge">{{ name }}</span>{% match note %}{% when Some with (n) %} <span class="italic text-faint break-words" aria-label="{{ tr.t("recipe-preparation") }}: {{ n }}">({{ n }})</span>{% when None %}{% endmatch %}{% when crate::web::templates::StepItem::Timer with { display, seconds } %}{% match seconds %}{% when Some with (secs) %}<span class="timer-badge" data-timer data-timer-key="{{ section_index }}-{{ step.number }}-{{ item_index }}" data-seconds="{{ secs }}" data-display="{{ display }}" data-section="{% match section.name %}{% when Some with (n) %}{{ n }}{% when None %}{% endmatch %}" data-step="{{ step.number }}" role="button" tabindex="0">⏱️ {{ display }}</span>{% when None %}<span class="timer-badge">⏱️ {{ display }}</span>{% endmatch %}{% when crate::web::templates::StepItem::Quantity with (qty) %}<span class="font-bold text-accent-text">{{ qty }}</span>{% when crate::web::templates::StepItem::LineBreak %}<br>{% endmatch %}{% endfor %}

Analysis and recommendations/changes made by Claude, posted on behalf of @LeMyst.

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

Successfully merging this pull request may close these issues.

2 participants