'New to OrgMode'

I am using org-outlook to capture email from outlook as task. I have a file ToDo.org with different multi-level headings. Looking for a way to put task under a specific heading.

Right now I am using file+function in capture template:

("u" "mycv" entry (file+function "~/Private/OrgMode/ToDo.org"
                 (lambda () (let ((org-goto-interface 'outline-path-completion))

This gives me an option to select heading/sub-heading from file but but I want to automate this step as well, if I can read Heading info from the link coming from outlook. I can customize VBA to include any info...

1 Answer 1


If you know the filename and the sequence of headlines under which you want to capture the new item, then you just need a file+olp target as described in the doc string of org-capture-templates. The entry would look like this:

("u" "mycv" entry (file+olp "~/Private/OrgMode/ToDo.org" "Level 1 Headline" "Level 2 Headline" ...) <some template>)

If the headline under which you want the new item is unique in the file, you can get away with a simpler target: (file+headline <file> <headline>), but the full-path specification of file+olp is safer in the long term.

See the doc string of org-capture-templates with C-h v org-capture-templates:

   (file+headline "path/to/file" "node headline")
        Fast configuration if the target heading is unique in the file

    (file+olp "path/to/file" "Level 1 heading" "Level 2" ...)
        For non-unique headings, the full outline path is safer

EDIT: if you want the outline path to be dynamically constructed, then you'll have to construct the org-capture-templates entry at runtime, and let-bind org-capture-templates around a call to org-capture in a function of your own. Since you don't provide an interface, I'm going to make some assumptions and write a function based on those assumptions, but I hope what you have to do will be clear enough so that you can tweak the function to your requirements.

The basic assumption is that somebody constructs a list of headlines under which the new item is to be inserted. The list is sorted by headline level, so that if you want the new entry to go into a file my.org under the following headlines:

* foo
** bar
*** baz
<new item goes here>

the required list will be ("foo" "bar" "baz") in that order.

Based on that assumption, you can write a function that takes the path of the file, an olp list and the text of your new entry as arguments and does what it needs to have the new entry inserted in the specified place:

(defun my/insert-item-in-olp-hierarchy (path olp entry)
  (let ((org-capture-templates
         `(("u" "mycv" entry
            (file+olp ,path ,@olp)
            ,(format "* This is my new entry: %s" entry)
            :immediate-finish t))))
    (org-capture nil "u")))

You call it with something like this: (my/insert-item-in-olp-hierarchy "~/org/foo.org" '("foo" "bar" "baz") "My new entry")

The first level foo heading, second level bar heading and third level baz heading MUST already exist in the file or else you'll get an error. The new entry is inserted at the fourth level as specified by the template in the let-bound org-capture-templates. The function uses the backquote mechanism (read about it in the elisp manual: C-h i g(elisp)Backquote) to substitute in the path of the file and splice in the outline path list, as the file+olp entry type expects. And we specify :immediate-finish t, so that the new entry is entered directly in the file, without popping up a buffer to edit it before submitting it, since it's supposed to be self contained. For these details, careful study of the org-capture-templates doc string is warranted: see above for how to get the doc string.

This is just an example and you'll have to adapt it to your circumstances, but I think it contains all of the important elements you are looking for. Good luck!

  • Thanks for a detailed reply but headline hierarchy is not constant. Its dynamic and defined as part of link I am sending from Outlook.
    – RegMan
    Commented Oct 9, 2021 at 18:19
  • Then you'll have to write a function that constructs the entry dynamically, let-binds org-capture-templates so that it contains the new entry and then calls org-capture with the u argument so that the entry is used in the capture. I'll update the answer with an indication of how that would go.
    – NickD
    Commented Oct 9, 2021 at 19:44
  • Thanks NickD. I'll wait for it...
    – RegMan
    Commented Oct 10, 2021 at 9:57
  • Example of dynamic capture added.
    – NickD
    Commented Oct 12, 2021 at 2:20
  • 1
    Perfect! Thanks. I was thinking that this code will overwrite org-capture-templates variable and I'll lose all other templates but looks like its working fine and I still have my templates from init.el . (though I have no idea why its not overwriting org-capture-templates defined in init.el, maybe some scoping in lisp)
    – RegMan
    Commented Oct 13, 2021 at 4:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.