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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions