datasette icon indicating copy to clipboard operation
datasette copied to clipboard

Ability to set a custom favicon

Open simonw opened this issue 2 years ago • 12 comments

If you're running a website on Datasette, like https://www.niche-museums.com/ or https://til.simonwillison.net/ - you should have the ability to easily specify a custom favicon.

Currently the /favicon.ico view is hard-coded to do this: https://github.com/simonw/datasette/blob/9f1eb0d4eac483b953392157bd9fd6cc4df37de7/datasette/app.py#L179-L188

simonw avatar Jul 05 '22 18:07 simonw

Some options:

  • Allow favicon path to be set in metadata.yml somehow, or via a --setting
  • Teach Datasette to check for templates/favicon.ico and fall back to the default static/favicon.png if that file does not exist
  • Document how to over-ride the favicon using the existing --static mechanism (if that's even possible)
  • Outsource this to a new plugin

Note that I need a way to set the content_type correctly too.

simonw avatar Jul 05 '22 18:07 simonw

I think I want this to be a default feature, not a plugin.

simonw avatar Jul 05 '22 18:07 simonw

Loading it using the existing templating system would be better I think, since that way both custom installations AND plugins could influence the favicon in the same way that they influence the templates.

simonw avatar Jul 05 '22 18:07 simonw

The content type thing is a bit weird because usually I'd base that on the file extension, but here the favicon.ico file extension doesn't necessarily reflect if the image itself is a PNG or some other thing.

simonw avatar Jul 05 '22 18:07 simonw

Annoyingly it looks like the standard library mimetypes module only uses filenames as the clue, it doesn't look at the bytes themselves.

I'm using that here: https://github.com/simonw/datasette/blob/9f1eb0d4eac483b953392157bd9fd6cc4df37de7/datasette/utils/asgi.py#L261-L277

https://pypi.org/project/python-magic/ can inspect files, but I don't want to add a whole new dependency just for this one feature.

simonw avatar Jul 05 '22 18:07 simonw

I could use the imghdr standard library module, but frustratingly it's marked as deprecated in Python 3.11! https://docs.python.org/3/library/imghdr.html

simonw avatar Jul 05 '22 18:07 simonw

I could vendor the necessary parts of imghdr - it's pretty tiny: https://github.com/python/cpython/blob/3.11/Lib/imghdr.py

simonw avatar Jul 05 '22 18:07 simonw

https://www.w3.org/2005/10/howto-favicon suggests that it only needs to be able to identify PNG, GIF or ICO.

simonw avatar Jul 05 '22 18:07 simonw

Based on https://github.com/python/cpython/blob/3.11/Lib/imghdr.py I'm tempted to say that if the file starts with b'\211PNG\r\n\032\n' then it's a PNG, if it starts with b'GIF8 then it's a GIF, anything else I assume an ICO.

simonw avatar Jul 05 '22 18:07 simonw

Came up in office hours again today.

simonw avatar Jan 12 '24 23:01 simonw

It might be helpful to have a little library of Datasette favicons. One for documentation, one for cloud, one for default Datasette, one for the Substack, and maybe some others colors to make it easier to keep track of which ports and datasettes are which.. Maybe even a set with the datasette logo, with superimposed labels 1, 2, and 3, in case we have three different ports running at a time. (Hmm... I see the Substack already does have a slightly different favicon color and maybe different size as well. Different enough to be able to distinguish the tabs. That's helpful.)

mroswell avatar Jan 13 '24 07:01 mroswell

Maybe a little favicon designer hackathon, too! (The current default icon is VERRRY nerdy--maybe appropriate, but a slightly less nerdy favicon might be a draw?) The current icon also defaults (on my screen, anyhow) to a light color icon on a light color tab background. Doesn't stand out much. (Personally I couldn't create anything better, though). But now that Datasette can do so much ("multitool"), maybe the favicon should reflect that.

mroswell avatar Jan 13 '24 07:01 mroswell