Make a README badge with {badgr}

Badger from children's TV show Bodger & Badger making a mess with instant mashed potato.

{badgr} is definitely a bodge (CBeebies via Giphy)

ℹ️ Note

Somehow I missed the existence of the {badger} package by Guangchuang Yu. It contains functions for several pre-baked badge types, plus badge_custom(). Download it from CRAN.

tl;dr

Sometimes a post on this blog is related to some code in a GitHub repository. I wanted to create a badge to link from that repo to the relevant post.

I’ve written a very basic package with a single very simple functionbadgr::get_badge()—that generates a URL for a shields.io badge, which can then be placed in a repo’s README.

Here’s what the badge looks like (note the icon is subtly animated):

What’s a badge?

You’ll see badges in the README files of code repositories on sites like GitHub and GitLab. They communicate something about the code at-a-glance and usually contain metadata or a link to further information.

Part of the README for the data.table package showing a number of badges, including test checks and download count.

Examples of badges in the repo README for {data.table}

Dynamic metadata badges help you judge the status of the repo. For example, a common badge is one that indicates whether the code has passed testing via a continuous integration service like Travis. So ‘build passing’ means that the code in the latest update is working. Clicking the badge will take you to the associated site to get more information.

Other badges are static and can act as a handy link. For example, some repos have badges for services like Ko-Fi for donations, or perhaps to open the repo in a cloud-based instance of Binder.

Roll your own

You can create your own badges for whatever purpose. I was particularly amused to see a ‘cool | useless’ badge in repos by mikefc (@coolbutuseless).

I want people to know if one of my GitHub repositories is related to a post on this blog so they can find out more. I could just link to the post in the README—I often do—but the badge sits at the top of the README and is eye-catching. It’s also a useful at-a-glance reminder for me when I’m looking over my repos.

You can see this badge (and others) in action in my repo for the {oystr} package, for example. The rest of this post lays out how you can build one for yourself.

shields.io

Fortunately, There’s a service called shields.io that makes it easy to create a simple badge. It works by exposing a badge with parameters you provide in a URL string.

You can generate a simple static badge by modifying a URL string in the form https://img.shields.io/badge/<LABEL>-<MESSAGE>-<COLOR>.

So ![](https://img.shields.io/badge/label-message-red) results in this:

You could build on this by providing an alternative style and an image from Simple Icons.

For example, ![](https://img.shields.io/badge/label-message-181717?style=for-the-badge&logo=github) results in this:

So you can see that additional ‘arguments’ to the basic call are added after a ? and then additional parts added with an &.

I’m not affiliated with shields.io. Find out more from their website, Twitter, Discord or go to the source code. If you find their service useful, you can donate.

{badgr}

This got me thinking about a quick R function to build up a badge URL. This became the get_badge() function in the {badgr} package. This is currently a bit janky and untested, but so far it does what I want it to do.

You can install it with:

remotes::install_githb("matt-dray/badgr")

get_badge() builds up the components of a shields.io-valid URL given the arguments you provide. For example, you can specify the text (label and message arguments) and background colour to go on either side of the badge (label_color and color). You can also include a logo from simpleicons.org (logo_simple) or a custom icon of your choosing (logo_path).

The most complex part is that the path to the custom logo has to be base64-encoded, which is done with base64enc::base64encode(). The output from that is then passed into the shields.io URL.

By default, the function wraps your badge in Markdown in the form [![](<shields.io URL>)](<provided link>) and copies it to your clipboard, ready for you to paste it into a README somewhere. It also sends the URL to your browser for a preview.

A rostrum.blog badge

So, I made a badge that has:

  • ‘rostrum.blog’ on the left side, with a black background
  • ‘post’ on the right side with a green background (to match the green used on this site)
  • the rostrum.blog ‘bug’ logo gif (used as the favicon for the site)1

I achieved that with the following code:

# Set path to custom logo (a gif in this case)
logo <- "https://raw.githubusercontent.com/matt-dray/rostrum-blog/master/static/images/favicon.gif"

# Set underlying badge link (where the badge-click will take you)
link <- "https://www.rostrum.blog/"

blog_badge <- badgr::get_badge(
  label = "rostrum.blog",   # left-side text
  message = "post",         # right-side text
  color = "008900",         # left-side colour (green)
  label_color = "black",    # right_side colour
  md_link = link,           # where to go when clicked
  logo_path = logo,         # path to my logo
  browser_preview = FALSE,  # don't open preview
  to_clipboard = FALSE      # don't copy to clipboard
)

That results in the following string output:

blog_badge
## [1] "[![](https://img.shields.io/badge/rostrum.blog-post-008900?style=flat&labelColor=black&logo=data:image/gif;base64,R0lGODlhEAAQAPEAAAAAABWCBAAAAAAAACH5BAlkAAIAIf8LTkVUU0NBUEUyLjADAQAAACwAAAAAEAAQAAAC55QkISIiEoQQQgghRBBCiCAIgiAIgiAIQiAIgSAIgiAIQiAIgRAEQiAQBAQCgUAQEAQEgYAgIAgIBAKBQBAQCAKBQEAgCAgEAoFAIAgEBAKBIBAQCAQCgUAgEAgCgUBAICAgICAgIBAgEBAgEBAgEBAgECAgICAgECAQIBAQIBAgECAgICAgICAgECAQECAQICAgICAgICAgEBAgEBAgEBAgICAgICAgECAQIBAQIBAgECAgICAgIBAgECAQECAQIBAgICAgIBAgIBAgEBAgECAgECAgICAgICAgECAgECAgQIAAAQIKAAAh+QQJZAACACwAAAAAEAAQAAAC55QkIiESIoQQQgghhAhCBCEIgiAIgiAIQiAIgSAIgiAIQiAIgRAEQiAQBAQCgUAQEAQEgYAgIAgIBAKBQBAQCAKBQEAgCAgEAoFAIAgEBAKBIBAQCAQCgUAgEAgCgUBAICAgICAgIBAgEBAgEBAgEBAgECAgICAgECAQIBAQIBAgECAgICAgICAgECAQECAQICAgICAgICAgEBAgEBAgEBAgICAgICAgECAQIBAQIBAgECAgICAgIBAgECAQECAQIBAgICAgIBAgIBAgEBAgECAgECAgICAgICAgECAgECAgQIAAAQIKAAA7)](https://www.rostrum.blog/)"

This is a shields.io-valid URL encased in some Markdown that allows it to be pasted directly into a GitHub README, for example.

It looks like this when rendered:

Note that clicking the badge in a README will link to wherever you set in the md_link argument. For some reason, the rendering inside this blog means that the badge contains the link (see how it’s underlined?), but you can’t click on the badge area to visit it. 🤷

Note that the icon is subtly animated (the bug antennae open and close) because the source image was a gif.

To see the badge in the wild, you can look in my repos for:

And many others.


Session info
## ─ Session info ───────────────────────────────────────────────────────────────
##  setting  value                       
##  version  R version 4.0.2 (2020-06-22)
##  os       macOS Mojave 10.14.6        
##  system   x86_64, darwin17.0          
##  ui       X11                         
##  language (EN)                        
##  collate  en_GB.UTF-8                 
##  ctype    en_GB.UTF-8                 
##  tz       Europe/London               
##  date     2020-12-27                  
## 
## ─ Packages ───────────────────────────────────────────────────────────────────
##  package     * version    date       lib source                          
##  assertthat    0.2.1      2019-03-21 [1] CRAN (R 4.0.0)                  
##  badgr         0.0.0.9000 2020-12-27 [1] Github (matt-dray/badgr@87a3e89)
##  base64enc     0.1-3      2015-07-28 [1] CRAN (R 4.0.0)                  
##  blogdown      0.19       2020-05-22 [1] CRAN (R 4.0.0)                  
##  bookdown      0.19       2020-05-15 [1] CRAN (R 4.0.0)                  
##  cli           2.2.0      2020-11-20 [1] CRAN (R 4.0.2)                  
##  clipr         0.7.1      2020-10-08 [1] CRAN (R 4.0.2)                  
##  crayon        1.3.4      2017-09-16 [1] CRAN (R 4.0.0)                  
##  digest        0.6.27     2020-10-24 [1] CRAN (R 4.0.2)                  
##  emo           0.0.0.9000 2020-05-24 [1] Github (hadley/emo@3f03b11)     
##  evaluate      0.14       2019-05-28 [1] CRAN (R 4.0.0)                  
##  fansi         0.4.1      2020-01-08 [1] CRAN (R 4.0.0)                  
##  generics      0.1.0      2020-10-31 [1] CRAN (R 4.0.2)                  
##  glue          1.4.2      2020-08-27 [1] CRAN (R 4.0.2)                  
##  htmltools     0.5.0      2020-06-16 [1] CRAN (R 4.0.2)                  
##  knitr         1.30       2020-09-22 [1] CRAN (R 4.0.2)                  
##  lubridate     1.7.9.2    2020-11-13 [1] CRAN (R 4.0.2)                  
##  magrittr      2.0.1      2020-11-17 [1] CRAN (R 4.0.2)                  
##  purrr         0.3.4      2020-04-17 [1] CRAN (R 4.0.0)                  
##  Rcpp          1.0.5      2020-07-06 [1] CRAN (R 4.0.2)                  
##  rlang         0.4.9      2020-11-26 [1] CRAN (R 4.0.2)                  
##  rmarkdown     2.5        2020-10-21 [1] CRAN (R 4.0.2)                  
##  rstudioapi    0.13       2020-11-12 [1] CRAN (R 4.0.2)                  
##  sessioninfo   1.1.1      2018-11-05 [1] CRAN (R 4.0.0)                  
##  stringi       1.5.3      2020-09-09 [1] CRAN (R 4.0.2)                  
##  stringr       1.4.0      2019-02-10 [1] CRAN (R 4.0.0)                  
##  withr         2.3.0      2020-09-22 [1] CRAN (R 4.0.2)                  
##  xfun          0.19       2020-10-30 [1] CRAN (R 4.0.2)                  
##  yaml          2.2.1      2020-02-01 [1] CRAN (R 4.0.0)                  
## 
## [1] /Library/Frameworks/R.framework/Versions/4.0/Resources/library

  1. Bear in mind that a very large image might not be that effective when squashed down to fit into the badge. The icon I’ve used is only 16x16, so is already small and looks fine in the badge.↩︎