Compare commits
10 commits
Author | SHA1 | Date | |
---|---|---|---|
2e5859342d | |||
ae3ee28ab4 | |||
8a9ae16ad3 | |||
cc9206306a | |||
3e3de7ea59 | |||
e35bc3852b | |||
7b3aa25c95 | |||
88f801cadb | |||
8046f0d237 | |||
08fce0ae16 |
26 changed files with 94 additions and 446 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,4 +4,3 @@ recipes
|
|||
venv
|
||||
.mypy_cache
|
||||
.vscode
|
||||
docs/book
|
||||
|
|
15
.woodpecker/containers.yaml
Normal file
15
.woodpecker/containers.yaml
Normal file
|
@ -0,0 +1,15 @@
|
|||
when:
|
||||
- event: push
|
||||
branch: main
|
||||
|
||||
steps:
|
||||
- name: publish
|
||||
image: woodpeckerci/plugin-docker-buildx
|
||||
settings:
|
||||
platforms: linux/amd64,linux/arm64/v8
|
||||
repo: git.comfy.city/emi/comfy-recipes
|
||||
registry: git.comfy.city
|
||||
tags: latest
|
||||
username: ${CI_REPO_OWNER}
|
||||
password:
|
||||
from_secret: registry_token
|
15
Dockerfile
15
Dockerfile
|
@ -1,12 +1,11 @@
|
|||
FROM alpine:3.18 AS build
|
||||
FROM python:3.13-alpine AS build
|
||||
COPY . /build
|
||||
WORKDIR /build
|
||||
RUN apk add --no-cache python3 py3-build py3-hatchling && \
|
||||
RUN pip install build hatchling && \
|
||||
python3 -m build .
|
||||
|
||||
FROM alpine:3.18
|
||||
COPY --from=build /build/dist/comfy-recipes-*-py3-none-any.whl /
|
||||
RUN apk add --no-cache python3 py3-pip && \
|
||||
pip install /comfy-recipes-*-py3-none-any.whl && \
|
||||
apk del py3-pip
|
||||
ENTRYPOINT ["/usr/bin/recipes-cli"]
|
||||
FROM python:3.13-alpine
|
||||
COPY --from=build /build/dist/ /mnt
|
||||
RUN pip install /mnt/comfy_recipes-*-py3-none-any.whl && \
|
||||
rm -r /mnt
|
||||
ENTRYPOINT ["/usr/local/bin/recipes-cli"]
|
||||
|
|
16
README.md
16
README.md
|
@ -4,7 +4,13 @@ Comfy Recipes is a simple application that renders your recipes into HTML.
|
|||
|
||||
Documentation is available at <https://comfy.city/comfy-recipes/docs>
|
||||
|
||||
## Building the python package
|
||||
## Running
|
||||
```sh
|
||||
docker run -v ./recipes:/recipes git.comfy.city/Emi/comfy-recipes:latest build /recipes
|
||||
```
|
||||
|
||||
## Building
|
||||
### Building the python package
|
||||
Make sure you have hatchling and build modules installed.
|
||||
```sh
|
||||
python3 -m build
|
||||
|
@ -15,17 +21,17 @@ The package can now be installed with
|
|||
pip install dist/comfy-recipes-*-py3-none-any.whl
|
||||
```
|
||||
|
||||
## Building the docker container
|
||||
### Building the docker container
|
||||
```sh
|
||||
docker build -t codeberg.org/comfy.city/comfy-recipes .
|
||||
docker buildx build -t git.comfy.city/Emi/comfy-recipes:local .
|
||||
```
|
||||
|
||||
The container can now be ran
|
||||
```sh
|
||||
docker run --rm codeberg.org/comfy.city/comfy-recipes
|
||||
docker run -v ./recipes:/recipes git.comfy.city/Emi/comfy-recipes:local build /recipes
|
||||
```
|
||||
|
||||
## Building the documentation
|
||||
### Building the documentation
|
||||
```sh
|
||||
cd docs
|
||||
mdbook build
|
||||
|
|
|
@ -197,19 +197,20 @@ class IngredientInstance(Element):
|
|||
def from_dict(cls, ctx: Context, dct: str | Dict[str, Any]) -> Self:
|
||||
if isinstance(dct, str):
|
||||
string = dct.strip()
|
||||
p = re.compile(r"^(?:([0-9\.]+) ([a-zA-Z]+) )?([\w ]+)(?: \((.*)\))?$")
|
||||
p = re.compile(r"^(?:([0-9\.]+) ([a-zA-Z]+) )+([\w ]+)(?: \((.*)\))?$")
|
||||
match = p.match(string)
|
||||
if match is None:
|
||||
raise RuntimeError(
|
||||
"ingredient {string} regex not matched, it should be in the format [amount(num) unit(string, one word)] name(string, any number of words) [(note(string))]"
|
||||
)
|
||||
|
||||
amount = float(1)
|
||||
unit = ctx.default_unit
|
||||
name = string
|
||||
note = None
|
||||
if match is not None:
|
||||
amount = float(match.group(1))
|
||||
unitstr = match.group(2)
|
||||
unit = ctx.default_unit
|
||||
if unit is not None:
|
||||
unitx = ctx.units.get(unitstr)
|
||||
if unitx is None:
|
||||
ctx.issues.error(issues.ISSUE_UNKNOWN_UNIT, "unknown unit {unitstr}")
|
||||
ctx.issues.error(issues.ISSUE_UNKNOWN_UNIT, f"unknown unit {unitstr}")
|
||||
else:
|
||||
unit = unitx
|
||||
name = match.group(3)
|
||||
|
@ -289,7 +290,7 @@ class Recipe(Element):
|
|||
source: Optional[SafeHTML],
|
||||
ingredients: List[IngredientInstance],
|
||||
subrecipes: List["Recipe"],
|
||||
price: Optional["PriceDB"],
|
||||
price: Optional["MultiPriceDB"],
|
||||
stepsections: List[StepSection],
|
||||
) -> None:
|
||||
super().__init__(ctx)
|
||||
|
@ -317,7 +318,7 @@ class Recipe(Element):
|
|||
rp = Recipe.from_dict(ctx, partdct)
|
||||
subrecipes.append(rp)
|
||||
|
||||
price: Optional[PriceDB] = None
|
||||
price: Optional[MultiPriceDB] = None
|
||||
pricex: float = 0
|
||||
ingswithprice = 0
|
||||
ingswithoutprice = 0
|
||||
|
@ -335,16 +336,22 @@ class Recipe(Element):
|
|||
# we don't know how to convert currencies yet
|
||||
currency = None
|
||||
break
|
||||
if currency is None or ingswithoutprice != 0 or len(ingredients) == 0:
|
||||
if currency is None or len(ingredients) == 0:
|
||||
price = None
|
||||
else:
|
||||
price = PriceDB(
|
||||
pricedb = PriceDB(
|
||||
ctx=ctx,
|
||||
price=pricex,
|
||||
amount=1,
|
||||
unit=ctx.default_unit,
|
||||
currency=currency,
|
||||
)
|
||||
price = MultiPriceDB(
|
||||
ctx=ctx,
|
||||
pricedb=pricedb,
|
||||
item_count=len(ingredients),
|
||||
item_prices_missing=ingswithoutprice,
|
||||
)
|
||||
|
||||
stepsections: List[StepSection] = []
|
||||
if "steps" in dct:
|
||||
|
@ -594,3 +601,16 @@ class PriceDB(Element):
|
|||
if currency is None:
|
||||
raise RuntimeError("currency not specified and default_currency is also not set")
|
||||
return cls(ctx=ctx, price=price, amount=amount, unit=unit, currency=currency)
|
||||
|
||||
class MultiPriceDB(Element):
|
||||
def __init__(
|
||||
self,
|
||||
ctx: Context,
|
||||
pricedb: PriceDB,
|
||||
item_count: int,
|
||||
item_prices_missing: int,
|
||||
) -> None:
|
||||
super().__init__(ctx)
|
||||
self.pricedb = pricedb
|
||||
self.item_count = item_count
|
||||
self.item_prices_missing = item_prices_missing
|
||||
|
|
|
@ -1,12 +1,24 @@
|
|||
{% macro price(price) -%}
|
||||
{% if price != None and price is defined and price.price is defined %}{{price.price|round(1)|numprint}}{%else%}?{% endif %} {{price.currency}}
|
||||
{%- endmacro %}
|
||||
{% macro multiprice(multiprice, shortform) -%}
|
||||
{% if multiprice != None and multiprice.pricedb != None and multiprice.pricedb is defined and multiprice.pricedb.price is defined -%}
|
||||
{{multiprice.pricedb.price|round(1)|numprint}}
|
||||
{%else%}
|
||||
?
|
||||
{%- endif %}
|
||||
{{multiprice.pricedb.currency}}
|
||||
{%if multiprice.item_prices_missing != 0 and not shortform%}
|
||||
({{multiprice.item_prices_missing}}/{{multiprice.item_count}} prices missing)
|
||||
{%endif%}
|
||||
{%- endmacro %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css@2/out/water.css">
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
</head>
|
||||
<body>
|
||||
{% block body %}{% endblock %}
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
{%block body %}
|
||||
<h1>Recipes</h1>
|
||||
{% for recipe in recipes %}
|
||||
<li>{% if recipe.price != None %}{{price(recipe.price)}} {%endif%}<a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
|
||||
<li>{% if recipe.price != None %}{{multiprice(recipe.price, true)}} {%endif%}<a href="{{ recipe.outpath }}">{{ recipe.title }}</a></li>
|
||||
{% endfor %}
|
||||
{%endblock%}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{% extends "base.html" %}
|
||||
{% macro ingredientpart(ing) -%}
|
||||
{% if recipe.price != None %}{{price(ing.price)}} {%endif%}
|
||||
{% if ing.price != None %}{{price(ing.price)}} {%endif%}
|
||||
{% if ing.amount != None %} {{ing.amount|amountprint}}
|
||||
{% if ing.unit != None %} {{ing.unit.name}}{% endif %}
|
||||
{%endif%}
|
||||
|
@ -29,7 +29,10 @@
|
|||
{% for ing in rec.ingredients %}
|
||||
<li>{{ingredient(ing)}}</li>
|
||||
{% endfor %}
|
||||
{% if rec.price != None %}price: {{price(rec.price)}}{%endif%}
|
||||
{% if rec.price != None %}
|
||||
<br>
|
||||
price: {{multiprice(rec.price)}}
|
||||
{%endif%}
|
||||
{% endif %}
|
||||
{% if rec.stepsections|length != 0 %}
|
||||
<h3>Steps</h3>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
[book]
|
||||
authors = ["Emi Vasilek"]
|
||||
language = "en"
|
||||
multilingual = false
|
||||
title = "Comfy Recipes Documentation"
|
||||
|
||||
[build]
|
||||
create-missing = true
|
||||
|
||||
[output.html]
|
||||
preferred-dark-theme = "Ayu"
|
||||
git-repository-url = "https://codeberg.org/comfy.city/comfy-recipes"
|
||||
git-repository-icon = "fa-git"
|
|
@ -1,15 +0,0 @@
|
|||
title: Swedish Pancakes
|
||||
ingredients:
|
||||
- 3 piece egg
|
||||
- 1.25 cup milk
|
||||
- 0.75 cup all purpose flour
|
||||
- 1 tablespoon white sugar
|
||||
- 1 tablespoon butter
|
||||
steps:
|
||||
- Beat eggs in a bowl until the mixture is smooth.
|
||||
- Add milk
|
||||
- Mix flour, sugar and salt in a separate bowl
|
||||
- Mix together with the egg mixture, mix until it's smooth
|
||||
- heat a griddle
|
||||
- Drop just enough of the mixture to the griddle to spread to all corners
|
||||
- After about a minute, turn the pancake over
|
|
@ -1 +0,0 @@
|
|||
- title: Pancakes
|
|
@ -1,5 +0,0 @@
|
|||
- title: Pancakes
|
||||
ingredients:
|
||||
- 100 gram flour
|
||||
steps:
|
||||
- make pancakes
|
|
@ -1,14 +0,0 @@
|
|||
# Summary
|
||||
|
||||
- [Introduction](./introduction.md)
|
||||
- [Installation](./installation.md)
|
||||
- [Tutorial](./tutorial/index.md)
|
||||
- [Quick Start](./tutorial/quickstart.md)
|
||||
- [Units](./tutorial/units.md)
|
||||
- [Ingredients](./tutorial/ingredients.md)
|
||||
- [Prices and Conversions](./tutorial/pricesconversions.md)
|
||||
- [Reference](./reference/index.md)
|
||||
- [Recipe (recipes/*.yaml)](./reference/recipe.md)
|
||||
- [Units (units.yaml)](./reference/units.md)
|
||||
- [Ingredients (ingredients.yaml)](./reference/ingredients.md)
|
||||
- [Settings (settings.yaml)](./reference/settings.md)
|
|
@ -1,14 +0,0 @@
|
|||
# Installation
|
||||
## Docker
|
||||
The containers are available on <https://codeberg.org/comfy.city/-/packages/container/comfy-recipes/latest>
|
||||
```sh
|
||||
docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes ARGUMENTS
|
||||
```
|
||||
|
||||
for example:
|
||||
```sh
|
||||
docker run --rm -v path/to/myrecipes:/mnt codeberg.org/comfy.city/comfy-recipes build /mnt
|
||||
```
|
||||
|
||||
---
|
||||
Docker is currently the only supported installation method, if you would like to use another method, please refer to the building instructions which are available in the project [README.md](https://codeberg.org/comfy.city/comfy-recipes/src/branch/main/README.md)
|
|
@ -1,22 +0,0 @@
|
|||
# Introduction
|
||||
|
||||
Comfy Recipes is a program that allows you to create a rich collection of recipes and create a presentable website from them.
|
||||
|
||||
## Get started
|
||||
If you don't have comfyrecipes installed yet, please see [Installation](./installation.md)
|
||||
|
||||
1. write a recipe in a yaml format to `myrecipes/recipes/xxxx.yaml`, for example
|
||||
|
||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||
```yaml
|
||||
{{#include ../examples/firstrealrecipe.yaml}}
|
||||
```
|
||||
|
||||
2. run `comfyrecipes build myrecipes/` (this will build the website to `myrecipes/out/html`)
|
||||
3. run `comfyrecipes serve` myrecipes and navigate to <http://localhost:8000> (this will run a web server and allow you to see your rendered recipe)
|
||||
|
||||
## Links
|
||||
* Repository: <https://codeberg.org/comfy.city/comfy-recipes>
|
||||
* Issues: <https://codeberg.org/comfy.city/comfy-recipes/issues>
|
||||
* Website: <https://comfy.city/comfy-recipes>
|
||||
* Documentation: <https://comfy.city/comfy-recipes/docs>
|
|
@ -1,15 +0,0 @@
|
|||
# Reference
|
||||
|
||||
* What's not marked as **MANDATORY** is optional.
|
||||
|
||||
## Data Types
|
||||
* `string` - text of arbitrary length
|
||||
* `integer` - a whole number
|
||||
* `float` - a decimal number
|
||||
* `number` - `integer` or `float`
|
||||
|
||||
## Table Of Contents
|
||||
* [Recipes](recipe.md) - documenting recipes/*.yaml
|
||||
* [Units](units.md) - documenting units.yaml
|
||||
* [Ingredients](ingredients.md) - documenting ingredients.yaml
|
||||
* [Settings](settings.md) - documenting settings.yaml
|
|
@ -1,20 +0,0 @@
|
|||
# Ingredients (ingredients.yaml)
|
||||
- list of [Ingredient](#ingredient)
|
||||
|
||||
## Ingredient
|
||||
- name, **MANDATORY**, string
|
||||
- aliases, list of strings
|
||||
- wdid, integer
|
||||
- prices, list of [Prices](#price)
|
||||
- conversions, list of [Conversions](#conversion)
|
||||
|
||||
## Price
|
||||
- price, **MANDATORY**, number
|
||||
- amount, **MANDATORY**, number
|
||||
- unit, **MANDATORY**, string, unit has to be listed in units.yaml if units.yaml exists
|
||||
- currency, string
|
||||
|
||||
## Conversion
|
||||
- from, **MANDATORY**, string, from has to be listed in units.yaml if units.yaml exists
|
||||
- to, **MANDATORY**, string, to has to be listed in units.yaml if units.yaml exists
|
||||
- ratio, **MANDATORY**, number
|
|
@ -1,54 +0,0 @@
|
|||
# Recipe (recipes/*.yaml)
|
||||
- title - **MANDATORY**, string
|
||||
- ingredients - list of [Simplified Ingredients](#simplified-ingredient) and [Ingredients](#ingredient)
|
||||
- steps - list of strings and [Steps Sections](#steps-section)
|
||||
- subrecipes - list of [Recipes](#recipe-recipesyaml)
|
||||
|
||||
## Simplified Ingredient
|
||||
= string in a specific format
|
||||
```
|
||||
[amount unit] ingredient name [(note)]
|
||||
```
|
||||
[] means these sections are optional
|
||||
|
||||
* `amount` - number
|
||||
* `unit` - a single word string
|
||||
* `name` - string with arbitrary content
|
||||
* `note` - string with arbitrary content, but has to be enclosed in parentheses, otherwise it will be considered to be part of `name`
|
||||
|
||||
for example, valid values are:
|
||||
```
|
||||
1 piece carrot (sliced)
|
||||
^ amount
|
||||
^---^ unit
|
||||
^----^ ingredient name
|
||||
^-----^ note
|
||||
```
|
||||
```
|
||||
200 gram green onion
|
||||
^-^ amount
|
||||
^--^ unit
|
||||
^---------^ ingredient name
|
||||
```
|
||||
```
|
||||
apple
|
||||
^---^ ingredient name
|
||||
```
|
||||
```
|
||||
apple (red)
|
||||
^---^ ingredient name
|
||||
^---^ note
|
||||
```
|
||||
|
||||
When amount and unit is not in the string, it is assumed to be `1 piece`.
|
||||
|
||||
## Ingredient
|
||||
- name - **MANDATORY**, string, name has to be listed in ingredients.yaml if ingredients.yaml exists
|
||||
- amount - number
|
||||
- unit - string, unit has to be listed in units.yaml if units.yaml exists
|
||||
- or - list of [Ingredient](#ingredient)
|
||||
- note - string
|
||||
|
||||
## Steps Section
|
||||
- section - **MANDATORY**, string, section name
|
||||
- steps - list of strings
|
|
@ -1,2 +0,0 @@
|
|||
# Settings (settings.yaml)
|
||||
* default_currency, string
|
|
@ -1,13 +0,0 @@
|
|||
# Units (units.yaml)
|
||||
- list of [Units](#unit)
|
||||
|
||||
## Unit
|
||||
- name, **MANDATORY**, string
|
||||
- conversions, list of [Conversions](#conversion)
|
||||
- aliases, list of strings
|
||||
|
||||
## Conversion
|
||||
- to, **MANDATORY**, string, to has to be listed in units.yaml if units.yaml exists
|
||||
- ratio, **MANDATORY**, number
|
||||
|
||||
(this is similar to [Ingredients Conversion](./ingredients.md#conversion), but the `from` field is automatically set to unit's name)
|
|
@ -1,21 +0,0 @@
|
|||
# Tutorial
|
||||
|
||||
This is the full file structure of comfy recipes input data:
|
||||
|
||||
```
|
||||
- myrecipes/ - can be named according to your preference
|
||||
|
||||
- recipes/ - directory that will hold the recipes
|
||||
- pancakes.yaml - the individual recipe
|
||||
|
||||
- units.yaml - OPTIONAL, file containing all valid units and their properties
|
||||
- ingredients.yaml - OPTIONAL, file containing all valid ingredients and their properties
|
||||
- settings.yaml - OPTIONAL, file for overriding default settings
|
||||
```
|
||||
|
||||
In the following sub-chapters we will first create a simple recipe and then find out what each file does and what functionalities they can offer.
|
||||
|
||||
- [Quick Start](./quickstart.md) - Creating simple recipes
|
||||
- [Units](./units.md) - What units.yaml is for and how to use it
|
||||
- [Ingredients](./ingredients.md) - Why list ingredients in ingredients.yaml and what it can offer
|
||||
- [Prices and Conversions](./pricesconversions.md) - Let's start adding and calculating prices of recipes
|
|
@ -1,54 +0,0 @@
|
|||
# Ingredients
|
||||
|
||||
Similar to `units.yaml`, also `ingredients.yaml` is not a mandatory file, but having it gives us several advantages.
|
||||
* spelling mistakes are not silently ignored, if something is not listed in ingredients.yaml, comfyrecipes will warn you
|
||||
* we can use aliases - different names referring the same ingredient
|
||||
* we will be able to add some more data to ingredients that will allow us to calculate prices (described in [Prices and Conversions](./pricesconversions.md))
|
||||
|
||||
```
|
||||
- myrecipes/
|
||||
- recipes/
|
||||
- pancakes.yaml
|
||||
...
|
||||
- ingredients.yaml (we will be creating this file)
|
||||
```
|
||||
|
||||
We will again use the final recipe from [Quick Start](quickstart.md).
|
||||
|
||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||
```yaml
|
||||
{{#include ../../examples/firstrealrecipe.yaml}}
|
||||
```
|
||||
|
||||
If you don't want to write the file manually, we can generate it using:
|
||||
```sh
|
||||
$ comfyrecipes generate-ingredients
|
||||
```
|
||||
|
||||
This will generate a minimal ingredients.yaml:
|
||||
|
||||
`🗎 myrecipes/ingredients.yaml:`
|
||||
```yaml
|
||||
- name: all purpose flour
|
||||
- name: butter
|
||||
- name: egg
|
||||
- name: milk
|
||||
- name: white sugar
|
||||
```
|
||||
|
||||
Now, let's say we would want to call `all purpose flour` just `flour`, we can add an alias:
|
||||
|
||||
`🗎 myrecipes/ingredients.yaml:`
|
||||
```yaml
|
||||
- name: all purpose flour
|
||||
aliases:
|
||||
- flour
|
||||
- name: butter
|
||||
- name: egg
|
||||
- name: milk
|
||||
- name: white sugar
|
||||
```
|
||||
|
||||
Now whenever we add an ingredient called flour, it will be a reference to `all purpose flour`.
|
||||
|
||||
For a full reference for what an ingredients yaml can contain, please see the [Ingredients Reference](../reference/ingredients.md)
|
|
@ -1,27 +0,0 @@
|
|||
# Prices and Conversions
|
||||
|
||||
ComfyRecipes has the ability to compute recipe prices if we give it enough information.
|
||||
This requires your recipe collection to have an [`ingredients.yaml` file](./ingredients.md).
|
||||
Like with the previous sections, we will use
|
||||
|
||||
# Settings
|
||||
|
||||
Sometimes we need to configure some defaults globally, this is what settings.yaml is for.
|
||||
Currently it's only used for setting the default_currency.
|
||||
|
||||
Let's create settings.yaml and set the default currency to USD.
|
||||
|
||||
```
|
||||
- myrecipes/
|
||||
- recipes/
|
||||
- pancakes.yaml
|
||||
...
|
||||
- settings.yaml
|
||||
```
|
||||
|
||||
`🗎 myrecipes/settings.yaml:`
|
||||
```yaml
|
||||
default_currency: USD
|
||||
```
|
||||
|
||||
For a full reference for what a settings yaml can contain, please see the [Settings Reference](../reference/settings.md)
|
|
@ -1,65 +0,0 @@
|
|||
# Quick Start
|
||||
|
||||
Let's start writing recipes. First, create the directory structure that will hold all our input data.
|
||||
|
||||
```
|
||||
- myrecipes/
|
||||
- recipes/
|
||||
- pancakes.yaml
|
||||
```
|
||||
|
||||
Now when we have the structure created, let's create the most minimal possible `pancakes.yaml`:
|
||||
|
||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||
```yaml
|
||||
{{#include ../../examples/minimal.yaml}}
|
||||
```
|
||||
|
||||
And render it by running:
|
||||
```sh
|
||||
$ comfyrecipes build myrecipes
|
||||
```
|
||||
|
||||
This will create a new directory `out/` in `myrecipes/` containing the built data.
|
||||
```
|
||||
- myrecipes/
|
||||
- out/
|
||||
- html/
|
||||
- index.html
|
||||
- pancakes.html
|
||||
- recipes/
|
||||
- pancakes.yaml
|
||||
```
|
||||
|
||||
We can see the result if we start a web server pointing to that directory, for example by using:
|
||||
```sh
|
||||
$ comfyrecipes serve myrecipes
|
||||
```
|
||||
and navigate to <http://127.0.0.1:8000/>
|
||||
|
||||
`serve` should NOT be used in production.
|
||||
|
||||
While that was a valid recipe, it's not very useful and we can only see the title. Let's improve that:
|
||||
|
||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||
```yaml
|
||||
{{#include ../../examples/minimalusable.yaml}}
|
||||
```
|
||||
|
||||
* each ingredient is a step in the format `amount unit name`
|
||||
* `amount` has to be a number
|
||||
* `unit` has to be a single word
|
||||
* `name` can be a string with arbitrary content
|
||||
* for a full description of this format, please see the [Reference section](../reference/recipe.md#simplified-ingredient)
|
||||
* each step is a string with arbitrary content
|
||||
|
||||
And again, build, make sure the server is running and navigate to <http://127.0.0.1:8000/>. From now on, we will assume you know how to build and serve your output directory.
|
||||
|
||||
Once more, let's improve the recipe once again to something that can actually be made and is not just a demo. This does not introduce any new concepts compared to the last recipe we wrote.
|
||||
|
||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||
```yaml
|
||||
{{#include ../../examples/firstrealrecipe.yaml}}
|
||||
```
|
||||
|
||||
For a full reference for what a recipe yaml can contain, please see the [Recipe Reference](../reference/recipe.md)
|
|
@ -1,51 +0,0 @@
|
|||
# Units
|
||||
|
||||
Each recipe ingredient has a string unit assigned to it. This is great, but a centralized list of all alowed units with some additional properties has several advantages:
|
||||
|
||||
* spelling mistakes are not silently ignored, if you make a mistake in the ingredient unit name, comfyrecipes will warn you that it's not on the units list
|
||||
* `gram` and `g` can refer to the same unit (using aliases)
|
||||
* we can tell comfyrecipes unit conversion rates (for example 1000 gram = 1 kilogram) which it can then use for example for calculating prices
|
||||
|
||||
This example will use the final example from [Quick Start](quickstart.md).
|
||||
|
||||
`🗎 myrecipes/recipes/pancakes.yaml:`
|
||||
```yaml
|
||||
{{#include ../../examples/firstrealrecipe.yaml}}
|
||||
```
|
||||
|
||||
```
|
||||
- myrecipes/
|
||||
- recipes/
|
||||
- pancakes.yaml
|
||||
...
|
||||
- units.yaml (we will be creating this file)
|
||||
```
|
||||
|
||||
If you don't want to write the file manually, we can generate it using:
|
||||
```sh
|
||||
$ comfyrecipes generate-units
|
||||
```
|
||||
|
||||
This will generate a minimal units.yaml:
|
||||
|
||||
`🗎 myrecipes/units.yaml:`
|
||||
```yaml
|
||||
- name: cup
|
||||
- name: piece
|
||||
- name: tablespoon
|
||||
```
|
||||
|
||||
Now, let's say we would want to call `tablespoon` just `tbsp`, we can add an alias:
|
||||
|
||||
`🗎 myrecipes/units.yaml:`
|
||||
```yaml
|
||||
- name: cup
|
||||
- name: piece
|
||||
- name: tablespoon
|
||||
aliases:
|
||||
- tbsp
|
||||
```
|
||||
|
||||
Now we can rename the `tablespoon` unit in the recipe to `tbsp` and it will reference the `tablespoon` unit.
|
||||
|
||||
For a full reference for what a recipe yaml can contain, please see the [Units Reference](../reference/units.md)
|
|
@ -9,7 +9,7 @@ description = "Smart recipe static site generator"
|
|||
authors = [{ name = "Emi Vasilek", email = "emi.vasilek@gmail.com" }]
|
||||
keywords = ["recipes", "recipe", "static site generator"]
|
||||
requires-python = ">= 3.8"
|
||||
dependencies = ["jsonschema", "jinja2", "PyYAML", "mistune", "lxml"]
|
||||
dependencies = ["jsonschema", "jinja2", "PyYAML", "mistune", "lxml", "lxml_html_clean"]
|
||||
classifiers = [
|
||||
"Development Status :: 3 - Alpha",
|
||||
"Programming Language :: Python",
|
||||
|
@ -17,9 +17,9 @@ classifiers = [
|
|||
license = { file = "LICENSE" }
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://codeberg.org/comfy.city/comfy-recipes"
|
||||
Repository = "https://codeberg.org/comfy.city/comfy-recipes.git"
|
||||
Issues = "https://codeberg.org/comfy.city/comfy-recipes/issues"
|
||||
Homepage = "https://git.comfy.city/Emi/comfy-recipes"
|
||||
Repository = "https://git.comfy.city/Emi/comfy-recipes.git"
|
||||
Issues = "https://git.comfy.city/Emi/comfy-recipes/issues"
|
||||
Documentation = "https://comfy.city/comfy-recipes/docs"
|
||||
|
||||
[project.scripts]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue