Skip to content

:before-finalize and :after-finalize for Capture Templates or Documentation on Capture Events/Hooks #1129

@alecStewart1

Description

@alecStewart1

Does this feature exist in Emacs orgmode core?

Yes

Orgmode link

https://www.gnu.org/software/emacs/manual/html_node/org/Template-elements.html

Feature value

:before-finalize and :after-finalize have their uses. In the case of Emacs, you can add deadline to a captured task, pre-/post-transform any text you've captured before jumping to the capture, etc.

Now if this can be achieved currently by some hook or event that's associated with the capture functionality, I think that'd be worth documenting somewhere.

Additional context

While I'm looking into cutting down on the templates that I use, here's what I currently have in org-capture-templates in Emacs (using doct) to give an idea of some the more "complex" things :before-finalize / :after-finalize open up to you.

(("t" "Tasks")
 ("tD" "Today (Clocked)" entry (file+function "/Users/alec/Documents/Org/Tasks/Today.org" (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))) #'doct--fill-template :clock-in
  t :clock-keep t :clock-resume t :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Today (Clocked)" :keys "D" :type entry :file "/Users/alec/Documents/Org/Tasks/Today.org" :function (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))
   :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/weekly-clocked-tasks.tmplt" :before-finalize (lambda nil (funcall-interactively #'org-deadline nil (current-time))) :clock-in t
   :clock-keep t :clock-resume t :inherited-keys "tD" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("tt" "Time tracking")
 ("ttt" "Tasks" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO Task %^{Task Name } :task: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before 1
  :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Tasks" :type entry :keys "t" :template "* TODO Task %^{Task Name } :task: \n %?" :inherited-keys "ttt" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org" :clock-in t :clock-keep
   t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("ttm" "Meetings" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO Meeting %^{Meeting Name } :meeting: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before 1
  :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Meetings" :type entry :keys "m" :template "* TODO Meeting %^{Meeting Name } :meeting: \n %?" :inherited-keys "ttm" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org" :clock-in t
   :clock-keep t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("ttp" "Phone" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO Phone Call %^{Phone Call Subject } :phone: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before
  1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Phone" :type entry :keys "p" :template "* TODO Phone Call %^{Phone Call Subject } :phone: \n %?" :inherited-keys "ttp" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org"
   :clock-in t :clock-keep t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("tto" "Other" entry (file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org") "* TODO %^{What are we doing? } :other: \n %?" :clock-in t :clock-keep t :clock-resume t :empty-lines-before 1
  :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Other" :type entry :keys "o" :template "* TODO %^{What are we doing? } :other: \n %?" :inherited-keys "tto" :file "/Users/alec/Documents/Org/Tasks/Time-Tracking.org" :clock-in t
   :clock-keep t :clock-resume t :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("tm" "Today (Manual)" entry (file+function "/Users/alec/Documents/Org/Tasks/Today.org" (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))) #'doct--fill-template
  :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Today (Manual)" :keys "m" :type entry :file "/Users/alec/Documents/Org/Tasks/Today.org" :function (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))
   :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/weekly-manual-tasks.tmplt" :inherited-keys "tm" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t
   :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("td" "Today (Unclocked)" entry (file+function "/Users/alec/Documents/Org/Tasks/Today.org" (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))) #'doct--fill-template
  :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Today (Unclocked)" :keys "d" :type entry :file "/Users/alec/Documents/Org/Tasks/Today.org" :function (lambda nil (capture:goto-or-create-heading #'capture:get-todays-timestamp))
   :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/weekly-unclocked-tasks.tmplt" :before-finalize (lambda nil (funcall-interactively #'org-deadline nil (current-time)))
   :inherited-keys "td" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("th" "Habits")
 ("thd" "Daily" entry (file "/Users/alec/Documents/Org/Tasks/Habits.org") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Daily" :keys "d" :type entry :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/daily-habit.tmplt" :inherited-keys "thd" :file
   "/Users/alec/Documents/Org/Tasks/Habits.org" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("thD" "Every Other Day" entry (file "/Users/alec/Documents/Org/Tasks/Habits.org") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :jump-to-captured t :unnarrowed t :doct
  (:doct-name "Every Other Day" :keys "D" :type entry :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/bidaily-habit.tmplt" :inherited-keys "thD" :file
   "/Users/alec/Documents/Org/Tasks/Habits.org" :jump-to-captured t :immediate-finish t :empty-lines-before 1 :unnarrowed t :after-finalize
   (lambda nil (org-update-statistics-cookies t) (org-mode-restart))))
 ("c" "Calendar") ("ca" "Appointment")
 ("cad" "On day" entry (file+headline "/Users/alec/Documents/Org/Tasks/Calendar.org" "Appointments") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :unnarrowed t :doct
  (:doct-name "On day" :keys "d" :type entry :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/appt.tmplt" :inherited-keys "cad" :headline "Appointments" :file
   "/Users/alec/Documents/Org/Tasks/Calendar.org" :empty-lines-before 1 :immediate-finish t :unnarrowed t))
 ("caD" "At time" entry (file+headline "/Users/alec/Documents/Org/Tasks/Calendar.org" "Appointments") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :unnarrowed t :doct
  (:doct-name "At time" :keys "D" :type entry :headline "Appointments" :template-file "/Users/alec/.dots/emacs/.emacs.d/templates/capture/appt-time.tmplt" :inherited-keys "caD" :file
   "/Users/alec/Documents/Org/Tasks/Calendar.org" :empty-lines-before 1 :immediate-finish t :unnarrowed t))
 ("c" "Cookbook")
 ("cu" "From URL" entry (file "/Users/alec/Documents/Org/Mind/Cooking/Cookbook.org") "%(org-chef-get-recipe-from-url)" :empty-lines 1 :doct
  (:doct-name "From URL" :keys "u" :type entry :file "/Users/alec/Documents/Org/Mind/Cooking/Cookbook.org" :template "%(org-chef-get-recipe-from-url)" :inherited-keys "cu" :empty-lines 1))
 ("c" "Manual Entry" entry (file "/Users/alec/Documents/Org/cookbook.org")
  "* %^{Recipe title: }\n  :PROPERTIES:\n  :source-url:\n  :servings:\n  :prep-time:\n  :cook-time:\n  :ready-in:\n  :END:\n** Ingredients\n   %?\n**Directions %i %a" :empty-lines 1 :doct
  (:doct-name "Manual Entry" :type entry :file "/Users/alec/Documents/Org/cookbook.org" :template
   "* %^{Recipe title: }\n  :PROPERTIES:\n  :source-url:\n  :servings:\n  :prep-time:\n  :cook-time:\n  :ready-in:\n  :END:\n** Ingredients\n   %?\n**Directions %i %a" :inherited-keys "c" :empty-lines
   1))
 ("p" "Add Contact" entry (file "/Users/alec/Documents/Org/Just Notes/Phonebook.org") #'doct--fill-template :empty-lines-before 1 :immediate-finish t :doct
  (:doct-name "Add Contact" :keys "p" :empty-lines-before 1 :immediate-finish t :type entry :file "/Users/alec/Documents/Org/Just Notes/Phonebook.org" :template-file
   "/Users/alec/.dots/emacs/.emacs.d/templates/capture/contact.tmplt")))

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementEnhancement, not necessarily available in emacs

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions