Advanced bookmarking: combining LinkPreview API with TiddlyWIki?

Hello all!

For a project I am thinking of having a go at, I would like to have some sort of bookmarking. Where the user can add a URL of a newsarticle, and after pressing a button, a tiddler gets generated automatically with some info of that site.

https://www.linkpreview.net/ provided an API that generates a Json with info that would make it easy to create a tiddler I think. Here is an example:

{
   "title":"Google",
   "description":"Search webpages, images, videos and more.",
   "image":"https://www.google.com/images/logo.png",
   "url":"https://www.google.com"
}

The goal is to use the tiddler as a little card, just like when you paste a URL in a whatsapp or twitter message, it generates a preview. It would also open up possibilities as a bookmaker plugin where you donā€™t have to manually enter the info.

I mostly have experience with wikitext, some basic understanding of javascript and the documentation provides a sample script. I know that in tiddlywiki, you canā€™t manipulate the DOM with javascript. But is it possible to connect some javascript to a button widget? If so, do you have some pointers, of an example I can base it of?

Mostly trying to confirm if this idea is feasible before committing a weekend to it :stuck_out_tongue:

The following is not actually an answer to your question, but is an example of a quick ā€œbookmarkerā€ using the $droppable widget.

\define make_bookmark()
[ext[$(actionTiddler)$]]<br>
<iframe src="$(actionTiddler)$" style="width:100%;height:70vh;"></iframe>
\end

<$droppable actions="<$action-createtiddler $basetitle=<<actionTiddler>> text=<<make_bookmark>> />">
   <span title="drop URL here to create a bookmark">{{$:/core/images/link}}</span>
</$droppable>

To use, just drag a URL from your browserā€™s address bar and drop it on the ā€œlinkā€ icon.

It will automatically create a tiddler using the URL as the tiddler title and containing an external link to the URL as well as an iframe for embedding the site within the tiddler.

Note: many URLs block the use of iframes to display their site and will display ā€œconnection refusedā€ instead of showing the site content.

1 Like

I am not sure but suggest you have a look at the richlinks plugin which may be in the direction you are after.

Yes, one way to do it is to create a javascript macro. Hereā€™s an ā€œhello worldā€ example :

exports.name = "helloworld";

exports.params = [];

exports.run = function() {
 return "Hello World!";
};

In a tiddler with the type application/javascript and a field module-type set to macro.

Now you can use your macro in a button widget :

<$button set=<<unusedtitle baseName:"hello">> setTo=<<helloworld>> >

Create a new tiddler with the output of the macro helloworld

</$button>

There are probably much better ways to do this, so I hope someone more knowledgeable than me will provide some tips ^^

2 Likes

Thanks Eric and Tones for the reply! I am not looking for using Iframes. Instead, I want to use javascript to get a json with information with I want to create a tiddler from.

@telumire I copied your example to test, but the new tiddlers created are empty and titled ā€˜helloā€™, which should be ā€˜Hello Worldā€™ right? (i reloaded the entire wiki to load the new macro) Did we miss something?

Sometimes you need to reload the tab two times, try again.
You can test it out here : https://jstw.tiddlyhost.com/

1 Like

Because the result is asynchronous, you canā€™t use a javascript macro. It would have to be a a widget. But it should be possible. Hereā€™s code for a javascript macro that demonstrates the basic concept. Be sure to have a backup before trying:

/*\
title: link-info
type: application/javascript
module-type: macro

Macro to return a formatted version of the current time

\*/
(function(){

/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";

/*
Information about this macro
*/

exports.name = "linkinfo";

exports.params = [
	{name: "url"}
];

/*
Run the macro
*/
exports.run = function(url) {
	return loadXMLDoc(url) ;
};

var xmlhttp;
function loadXMLDoc(url)
{
    xmlhttp=null;
if (window.XMLHttpRequest)
  {// code for all new browsers
      xmlhttp=new XMLHttpRequest();
  }
else if (window.ActiveXObject)
  {// code for IE5 and IE6
      xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
if (xmlhttp!=null)
  {
      xmlhttp.onreadystatechange=state_Change;
      xmlhttp.open("GET",url,true);
      xmlhttp.send(null);
      xmlhttp.responseTest ;
  }
else
  {
      alert("Your browser does not support XMLHTTP.");
  }
}

function state_Change()
{ //console.log(xmlhttp.readyState) ;
    if (xmlhttp.readyState==4)
      {// 4 = "loaded"
alert(xmlhttp.responseText) ;
          if (xmlhttp.status==200)
            {// 200 = OK
             //xmlhttp.data and shtuff
            // ...our code here...
        }
  else
        {
            alert("Problem retrieving data");
        }
  }
}


})();

You put this code in a tiddler with type application/javascript and module-type macro. Then save and reload. When Invoked like:

<<linkinfo "http://api.linkpreview.net/?key=123456&q=https://www.google.com">>

It pops up an alert showing you the JSON info. Maybe this will inspire someone with a more agile mind to write the widget :wink:

3 Likes

@Mark_S

Hey thanks! This is good inspiration :slight_smile:

1 Like

I have a widget now, just to demonstrate that it is possible. I have no idea how many sacred rules of TW development I have broken, or if it will scale.

Import this into your disposable TW file, save, and reload. In ā€œTest Tiddlerā€ click on the button. There will be an alert message which I forgot to get rid of, and a brand new tiddler will be created with the JSON string as contents.

The next steps would be to get rid of the alert, parse the JSON into fields, and change the url input so you donā€™t have to enter the ā€œpreviewā€ part by hand. But I have to do other things for awhile.

tiddlylink2021-12-18.json (6.0 KB)

1 Like

This version creates a tiddler with fields preview-title, url, description, and image. Thatā€™s enough that someone could create a template to view the tiddler as a site preview, like we get when quoting sites in Discourse.

It uses the returned title as the tiddler title by default, but you can specify your own base title if you prefer (the widget is based on ActionCreateTiddler and mostly works the same). You need to set up an account with LinkPreview to get a key. The supplied key 123456 just works with google (maybe youtube?).

tiddlylink2021-12-19.json (7.2 KB)

1 Like

Iā€™ve updated the launch screen, adapted the drag/drop from Eric, and added my own template for displaying links. Iā€™m sure someone else could do much better with the aesthetics. Sadly, our own TiddlyWiki.com doesnā€™t return an image or a description.

4 Likes

Hi @Mark_S !

hereā€™s my take on a template for showing bookmarks:

Each card has a little growing animation on hover. Clicking the card opens the link in a new tab. Clicking the little info icon opens the tiddler where the bookmark is stored in.

Try it on tiddlywiki.com with this json: bookmark template example.json (2.9 KB)
Feel free to use it!

4 Likes

Thatā€™s a really nice template! Iā€™m sure most people will prefer that to my ā€œBest HTML Practices (1990 ed.)ā€ approach.

You might consider using ā€œpreview-titleā€ instead of title for the display title. If you click the button or drag/drop the same URL a second time the process avoids overwriting the old tiddler by making a new tiddler with a number affixed. But the ā€˜preview-titleā€™ field keeps the original, complete title.

This packages up Ericā€™s adapted drag/drop zone, gives you a choice to view items with Odinā€™s template or mine, and includes sample previews.

Iā€™m not sure if the widget can be used from node or that will cause a cross-domain conflict. The error-catching part needs work. But maybe this can useful to someone.

tiddlylink2021-12-22.json (12.5 KB)

2 Likes

Neat. On Node, you could have the server fetch the preview data. I was experimenting with similar things with Bob before I started re-writing a real-time backend. Will come back and check this one out.

1 Like

Sorry if this is hijacking the thread, but I wanted to chime in about a plugin I wrote to do something like this last year, in case any of you find it helpful in terms of looking at the code or the general ideas behind it. I called it ā€œFirst Class URLsā€: GitHub - hoelzro/tiddlywiki-first-class-urls: An experimental plugin to make importing tiddlers easier

The name is a bit of a misnomer - all I use it for is dragging or pasting URLs into my wiki and creating tiddlers with information automatically populated from metadata in the target URLā€™s HTML via some Node-side code as @joshuafontany suggested. The code isā€¦not great, but Iā€™m happy to answer any questions about it, and I hope it proves useful!

6 Likes

@hoelzro I will have to install node to look, can you share a short video example please?

I am very interested and currently use bob.exe to host node wikis so may need a separate install.

  • I recently also started using chrome as follows; chrome:favicon/https://domainname to extract icon files, but there are other methods, but this would help in your solution to make the links graphically meaningful as well (If you are not already doing this.
  • I would be keen to know if your solution can pull additional html data see this topic Thinking outside the box, well outside TiddlyWiki - wiki tags to allow rich links to other tiddlywikis.
1 Like

@TW_Tones Sure, hereā€™s an example of the plugin in action: first class urls example - YouTube

It might work with bob as long as bob can load custom route modules and import Node modules; Iā€™m not sure if this is the case or not! I have a goal of removing the Node-side route if I can, since I have to drag in a bunch of npm dependencies for the HTML processing :frowning:

I originally wanted to have custom/nice rendering of links brought in via this plugin, but I have focused almost entirely on the import and metadata extraction stuff - I think it wouldnā€™t be super hard to add extra metadata to at least allow other plugins akin to richlinks to display a domainā€™s favicon.

Regarding your second question, Iā€™ll have to read your thread when I have a little more time, but one of the current weaknesses of the plugin is, ironically, importing data from other TiddlyWikis! Iā€™d like to fix that in a new release, but I sadly havenā€™t had a lot of time for this plugin lately.

1 Like

@hoelzro when or if you do look at recognising tw do ask. We can do quite a bit with the raw tags or even alter the html file via the save template.

Ps looks great in the video.

Nice viewtemplate, I can see you have created a mark/previewlink-template tiddler, but how did you make these tiddler rendered by the template? I try delete all the tags, but it still rendered using your template.


P.S. you may interested in GitHub - cbroms/link-previews: Link previews everywhere. , which write a aws worker that can run in GitHub - cloudflare/miniflare: šŸ”„ Fully-local simulator for Cloudflare Workers . And you can open his website to try his aws worker (donā€™t abuse it). And I made a link preview plugin based on this worker tiddlywiki-plugins/plugins/linonetwo/preview-website at master Ā· tiddly-gittly/tiddlywiki-plugins Ā· GitHub

1 Like