-
-
Notifications
You must be signed in to change notification settings - Fork 1
Selecting Origin
In Vino, the term "origin" denotes where a wine comes from, encompassing country, region, and appellation. Vino aims to provide maximum flexibility, enforcing minimal conventions and allowing extensions using hooks and the power of the Vulpea library.
The only convention Vino requires is that each region and appellation must link to a single country using the country meta attribute (in Vulpea terminology). Although theoretically possible to link to multiple countries, Vino will only recognise the first one in certain contexts. If you need to support multiple countries, please open a discussion.
For convenience (although Vino doesn't currently use this information), you can also set parents for regions and appellations. Refer to vino-region-create and vino-appellation-create for details.
When selecting a wine origin (either when creating a new entry or updating an existing entry's origin), Vino uses vino-origin-select-fn, which defaults to vino-origin-select-by-country. This function operates in two steps: first, select a country, then select a region or appellation connected to that country.

If you prefer a 'flat' selection style, where you choose a region/appellation from a list of all regions and appellations in your notes directory, set the vino-origin-select-fn as follows:
(setq vino-origin-select-fn #'vino-origin-select-flat)You can implement your own origin selection function. The function must accept no arguments and return an association list containing a country and optionally a region and/or appellation. Below is the implementation of vino-origin-select-flat for illustration:
(defun vino-origin-select-flat ()
"Select origin of a wine using flat strategy.
When region or appellation note does not exist, it is created
using `vino-region-create' or `vino-appellation-create' depending
on user decision.
Return list of country, region and appellation depending on the user
selection.
If region is selected, then country is _country_ meta value of the
selected region; appellation is nil.
If appellation is selected, the country is _country_ meta value of the
selected appellation; and region is _parent_ meta value of the selected
appellation.
When the function tries to access meta value which is not set, it raises
an error."
(let ((note
(vulpea-select-from
"Region or appellation"
(seq-filter
(lambda (note)
(seq-contains-p (vulpea-note-tags note) "wine"))
(vulpea-db-query-by-tags-some
'("appellation" "region")))))
country region appellation)
(unless (vulpea-note-id note)
(setq note (pcase (completing-read
(format "%s does not exist. What to do?"
(vulpea-note-title note))
'("Create region"
"Create appellation"
"Abort"))
(`"Create region"
(vino-region-create :title (vulpea-note-title note)))
(`"Create appellation"
(vino-appellation-create :title (vulpea-note-title note)))
(_ (error "Abort")))))
(setq country (vulpea-note-meta-get note "country" 'note))
;; country is required
(unless country
(error "No country is set in %s" (vulpea-note-title note)))
;; only one of them is set
(if (vulpea-note-tagged-any-p note "region")
(setq region note)
(setq appellation note))
(-filter
#'cdr
`(("country" . ,country)
("region" . ,region)
("appellation" . ,appellation)))))But you can tailor the flow for whatever you want. You can even return other keys if you need. See the following example for more inspiration.
Suppose you want to implement a smarter selection of regions and appellations for German wines and subregions for Champagne wines. The logic could be as follows:
- Select a country.
- If it's Germany, ask for a quality level (Wein, Landwein, Qualitätswein, or Prädikatswein).
- If Landwein is chosen, select one of the available Landwein appellations and use its parent as the region (if available).
- If Qualitätswein or Prädikatswein is chosen, use it as the appellation and also pick a region from the available winemaking regions.
- Otherwise, select a region/appellation from a list filtered by the selected country.
- If the selected appellation is Champagne, select a subregion.
- Return all information.
(defconst my-vino/germany/wein "b4afc600-1592-4830-8402-77961dbc595d")
(defconst my-vino/germany/qualitatswein "82861689-1a6c-47e9-90c2-71835759f92c")
(defconst my-vino/germany/pradikatswein "29744fde-ad06-4085-8490-00991be1947b")
(defconst my-vino/germany/landwein
'("b893b7ea-1888-4a7a-97ef-e837cff30df9"
"dc8c4787-73e3-4ffc-9f4d-393d49142cd8"
"f59b5ff2-098b-42c3-86ca-8e08641cdf94"
"15793fde-91b7-4a7a-bdcc-7c15fe864ce7"
"c07c9851-1ed6-4391-b2ca-08cdb4a8d7aa"
"27830cd0-ac57-4273-8d48-c253ce6c3dd5"
"a497a039-de97-40d8-8930-de60f70091f1"
"6c53e3e6-9758-4065-adfc-ed049278f82d"
"394903af-7980-4727-b76a-49dc334f195a"
"918ea808-4f7e-44ce-b0d3-939ac6c17297"
"93deceaf-85fe-46e5-9901-6a8dd92b4e4e"
"501260a7-8f55-4c6e-947f-ea832f463fcb"
"347ccf73-a124-4223-a6b7-b09ff397ce87"
"3949561f-7881-44ff-bb8f-10ed73573397"
"563e96aa-c8d2-4952-9fd2-22779e5234c5"
"8733af09-7135-4589-a56e-039dab3ba7b1"
"7a8348dd-999d-4b35-865a-9ad9de3095a1"
"eaaf74a6-f9e4-4e1c-87c5-353d9270421f"
"9e5353a5-c2da-4bb2-bc5d-ec09954d3c27"
"dddd3512-94c5-4225-b2db-7f84bb360632"
"9356a819-e53e-48c0-a408-fbc38a7fd8ed"
"cef1f2c5-2a04-423e-b14f-7892aaf77264"
"c79491b2-824f-4de8-b4d4-f89824a9c856"
"76ca5b68-eb8b-45c4-9826-6e4561142ff7"
"ae668fd4-4221-4f35-8f20-42ad6c421af7"
"190d3a9b-1fef-4344-a460-88f1b99c9ebc"))
(defconst my-vino/germany/regions
'("d132a2b6-5dda-4741-8a37-a918852b0b50"
"cb214156-1394-4fd1-bd3a-f6036f78b3d1"
"3025012e-f6c3-40b7-a6dd-931bb8274daa"
"f01f1c70-005c-4a4c-bf9b-11f97357894e"
"28aed8eb-0567-42a1-8885-f3098d3b3cd4"
"a5051493-9ef5-43a6-a9c5-4a7f8865ce1d"
"c12ca7ee-0a81-4ca7-9222-db77d8a3b6ca"
"a7607fef-e2c2-4df8-8e49-da195f82a14c"
"19ca3ef7-5b84-41f5-be47-3bcfbc41a25d"
"d7edf304-d970-4440-bad1-6a759662e851"
"aad73bdf-1f85-4d4c-b149-223688c9f748"
"4108c59d-cc0b-4335-905d-486c12d34c5b"
"6f0c9592-67c4-436e-a26d-8cbd43504c51"))
(defun my-vino-origin-select-custom ()
"Custom origin selection function.
This one handles some countries in a very custom/specific way.
See `vino-origin-select-fn' for more information."
(interactive)
(let ((country (vulpea-select-from
"Country"
(vulpea-db-query-by-tags-every '("wine" "country"))))
rora region appellation subregion)
(unless (vulpea-note-id country)
(when (y-or-n-p "Country %s doesn not exist. Would you like to create it?")
(setq country (vino-country-create (vulpea-note-title country)))))
(when (vulpea-note-id country)
(pcase (vulpea-note-title country)
("Germany"
(pcase (completing-read "Quality level: " '("wein" "landwein" "qualitätswein" "prädikatswein") nil t)
("wein"
(setq appellation (vulpea-db-get-by-id my-vino/germany/wein)))
("landwein"
(setq appellation (vulpea-select-from
"Landwein"
(vulpea-db-query-by-ids my-vino/germany/landwein)
:require-match t))
(setq region (vulpea-note-meta-get appellation "parent" 'note)))
("qualitätswein"
(setq appellation (vulpea-db-get-by-id my-vino/germany/qualitatswein))
(setq region (vulpea-select-from
"Region"
(vulpea-db-query-by-ids my-vino/germany/regions)
:require-match t)))
("prädikatswein"
(setq appellation (vulpea-db-get-by-id my-vino/germany/pradikatswein))
(setq region (vulpea-select-from
"Region"
(vulpea-db-query-by-ids my-vino/germany/regions)
:require-match t)))))
;; default case
(_ (setq rora (vulpea-select-from
"Region or appellation"
(->> (append (vulpea-db-query-by-tags-every '("wine" "region"))
(vulpea-db-query-by-tags-every '("wine" "appellation")))
(--filter (string-equal (vulpea-note-id country)
(vulpea-note-meta-get it "country" 'link)))
(--remove (vulpea-note-tagged-any-p it "subregion")))))
(unless (vulpea-note-id rora)
(setq rora (pcase (completing-read
(format "%s does not exist. What to do?"
(vulpea-note-title rora))
'("Create region"
"Create appellation"
"Abort"))
(`"Create region"
(vino-region-create :title (vulpea-note-title rora)
:country country))
(`"Create appellation"
(vino-appellation-create :title (vulpea-note-title rora)
:country))
(_ (error "Abort")))))
(if (vulpea-note-tagged-any-p rora "region")
(setq region rora)
(setq appellation rora))))
;; custom rules
;; -> champagne - pick subregion
(when (and appellation (string-equal "Champagne AOC" (vulpea-note-title appellation)))
(let ((subregions (vulpea-db-query-by-tags-every '("wine" "champagne" "subregion"))))
(setq subregion (vulpea-select-from "Subregion" subregions :require-match t))))
(-filter
#'cdr
`(("country" . ,country)
("region" . ,region)
("appellation" . ,appellation)
("subregion" . ,subregion))))))