7.2 KiB
+++ title = "Bookmark with Org-capture" author = ["Elia el Lazkani"] date = 2020-09-17 lastmod = 2021-05-27 tags = ["org-mode", "emacs", "org-capture", "org-web-tools", "org-cliplink"] categories = ["text-editors"] draft = false +++
I was reading, and watching, Mike Zamansky's blog post series about org-capture and how he manages his bookmarks. His blog and video series are a big recommendation from me, he is teaching me tons every time I watch his videos. His inspirational videos were what made me dig down on how I could do what he's doing but... my way...
I stumbled across this blog post that describes the process of using org-cliplink
to insert the title of the post into an org-mode link. Basically, what I wanted to do is provide a link and get an org-mode link. Sounds simple enough. Let's dig in.
Org Capture Templates
I will assume that you went through Mike's part 1 and part 2 posts to understand what org-capture-templates
are and how they work. I essentially learned it from him and I do not think I can do a better job than a teacher.
Now that we understand where we need to start from, let's explain the situation. We need to find a way to call org-capture
and provide it with a template. This template will need to take a url and add an org-mode url in our bookmarks. It will look something like the following.
(setq org-capture-templates
'(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks")
"** %(some-function-here-to-call)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)))
I formatted it a bit so it would have some properties. I simply used the %t
to put the timestamp of when I took the bookmark. I used the %?
to drop me at the end for editing. Then some-function-here-to-call
a function to call to generate our bookmark section with a title.
The blog post I eluded to earlier solved it by using org-cliplink. While org-cliplink
is great for getting titles and manipulating them, I don't really need that functionality. I can do it manually. Sometimes, though, I would like to copy a page... Maybe if there is a project that could attempt to do someth... Got it... org-web-tools.
Configuring org-capture with org-web-tools
You would assume that you would be able to just pop (org-web-tools-insert-link-for-url)
in the previous block and you're all done. But uhhh....
Wrong number of arguments: (1 . 1), 0
No dice. What would seem to be the problem ?
We look at the definition and we find this.
(defun org-web-tools-insert-link-for-url (url)
"Insert Org link to URL using title of HTML page at URL.
If URL is not given, look for first URL in `kill-ring'."
(interactive (list (org-web-tools--get-first-url)))
(insert (org-web-tools--org-link-for-url url)))
I don't know why, exactly, it doesn't work by calling it straight away because I do not know emacs-lisp at all. If you do, let me know. I suspect it has something to do with (interactive)
and the list provided to it as arguments.
Anyway, I can see it is using org-web-tools--org-link-for-url
, which the documentation suggests does the same thing as org-web-tools-insert-link-for-url
, but is not exposed with (interactive)
. Okay, we have bits and pieces of the puzzle. Let's put it together.
First, we create the function.
(defun org-web-tools-insert-link-for-clipboard-url ()
"Extend =org-web-tools-inster-link-for-url= to take URL from clipboard or kill-ring"
(interactive)
(org-web-tools--org-link-for-url (org-web-tools--get-first-url)))
Then, we set our org-capture-templates
variable to the list of our only item.
(setq org-capture-templates
'(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks")
"** %(org-web-tools-insert-link-for-clipboard-url)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)))
Now if we copy a link into the clipboard and then call org-capture
with the option b
, we get prompted to edit the following before adding it to our bookmarks.
** [[https://cestlaz.github.io/stories/emacs/][Using Emacs Series - C'est la Z]]
:PROPERTIES:
:TIMESTAMP: <2020-09-17 do>
:END:
Works like a charm.
Custom URL
What if we need to modify the url in some way before providing it. I have that use case. All I needed to do is create a function that takes input from the user and provide it to org-web-tools--org-link-for-url
. How hard can that be ?! uhoh! I said the curse phrase didn't I ?
(defun org-web-tools-insert-link-for-given-url ()
"Extend =org-web-tools-inster-link-for-url= to take a user given URL"
(interactive)
(let ((url (read-string "Link: ")))
(org-web-tools--org-link-for-url url)))
We can, then, hook the whole thing up to our org-capture-templates
and we get.
(setq org-capture-templates
'(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks")
"** %(org-web-tools-insert-link-for-clipboard-url)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)
("B" "Bookmark (Paste)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks")
"** %(org-web-tools-insert-link-for-given-url)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)))
if we use the B
, this time, it will prompt us for input.
Configure org-capture with org-cliplink
Recently, this setup has started to fail and I got contacted by a friend pointing me to my own blog post. So I decided to fix it. My old setup used to use org-cliplink but I moved away from it for some reason. I cannot remember why. It is time to move back to it.
In this setup, I got rid of the custom function to get the link manually. I believe that is why I moved but I cannot be certain. Anyway, nothing worked so why keep something not working right ?
All this means is that we only need to setup our org-capture-templates
. We can do so as follows.
(setq org-capture-templates
'(("b" "Bookmark (Clipboard)" entry (file+headline "~/path/to/bookmarks.org" "Bookmarks")
"** %(org-cliplink)\n:PROPERTIES:\n:TIMESTAMP: %t\n:END:%?\n" :empty-lines 1 :prepend t)
Now, you should have a working setup... org-cliplink
willing !
Conclusion
I thought this was going to be harder to pull off but, alas, it was simple, even for someone who doesn't know emacs-lisp, to figure out. I hope I'd get more familiar with emacs-lisp with time and be able to do more. Until next time, I recommend you hook org-capture
into your workflow. Make sure it fits your work style, otherwise you will not use it, and make your path a more productive one.