Org Capture 模版如何加条件判断?

我的模版里有个 :URL: %a,问题是当没有链接时变成 :URL: ,有什么办法加个条件判断,没有连接时候,什么都不加?

我试过

%(if-let ((s (org-store-link nil))) (format ":URL:      %s\n" s) "")

但是由于当前 buffer 总是 *Capture*org-store-link 总是返回 nil。

看看是否符合你的要求:

(defun insert-last-sotred-link ()
  (when org-stored-links
    (with-temp-buffer
      (org-insert-last-stored-link 1)
      (concat ":PROPERTIES:\n"
	      "  :URL: "
	      (buffer-substring (point-min) (1- (point-max)))
	      "\n  :END:"))))

(add-to-list 'org-capture-templates
	     `("t" "Test" entry (file "~/inbox.org")
	       ,(concat "* %U - %^{title}\n"
			"  %(insert-last-sotred-link)\n")))
1 个赞

试了下不行,insert-last-sotred-link 总是没输出,要自己每次先手动执行一次 M-x org-store-link,然后才行。

不是很懂你的意思,链接不是之前用 org-store-link 存起来的,那是哪里来的?你之前用 %a 不就是 org-store-link 的结果么

‘%a’

    Annotation, normally the link created with org-store-link.

我写那个函数的逻辑就是:当你有 org-store-link 存起来的链接时,就插入这个链接,否则就不插入,这和你的要求 有什么办法加个条件判断,没有连接时候,什么都不加? 不吻合吗?

%a 会在你 M-x org-capture 时的当前 buffer 自动生成(如果当前 buffer 支持 org link 的话),不需要手动 M-x org-store-link

懂你的意思了,我 %a 几乎不用所以前面误解了你的目的。看了下代码从 org-capture 前所在的 buffer 生成链接的行为是在进入 org-capture 并且选择模板前发生的,而模板填充的过程远在这之后,所以在模板里写函数调用 org-store-link 这条路子看起来是不行的……

(defun org-capture (&optional goto keys)
    ; ......
    (let* ((orig-buf (current-buffer))
	   (annotation (if (and (boundp 'org-capture-link-is-already-stored)
				org-capture-link-is-already-stored)
			   (plist-get org-store-link-plist :annotation)
			 (ignore-errors (org-store-link nil))))
    ; ......

没错。

Org Capture 这模版不给力,真正的模版语言都起码支持逻辑判断和循环。

把模版改成函数可以,但是太麻烦了,感觉还不如不用 org capture,自己从头实现一个,不就是生成字符串吗。

(defun foo ()
  (let ((orglink (org-store-link nil)))
    (if orglink
        ;; 有链接
        "* TODO %?
:PROPERTIES:
:ID:       %(org-id-new)
:CREATED:  %<%FT%T%z>
:URL:      %a
:END:"
      ;; 没链接
      "* TODO %?
:PROPERTIES:
:ID:       %(org-id-new)
:CREATED:  %<%FT%T%z>
:END:")))

(setq org-capture-templates
      '(("x" "test" entry (file "/tmp/test.org")
         (function foo))))

Update 好像可以用 org capture 提供 hook,清除掉,但估计还是挺折腾。这个问题就留着吧,影响也不大。

2 个赞

最近正好也有这个需求,然后发现可以从org-store-link-plist里取相应的元素来判断

(defun v-a-or-nothing ()
  (let ((v-a (plist-get org-store-link-plist :annotation)))
    (if (equal v-a "")
        ""
      (concat ":URL:" v-a "\n"))))
%(v-a-or-nothing)
1 个赞