DEV Community

Dave Parr
Dave Parr

Posted on • Updated on • Originally published at daveparr.info

Posting from .Rmd to dev.to

I’ve started making an R package called
dev.to.ol. Dev.to has an api
which is in beta
, which I’m using to power
the package.

Prototype

The first function was really just to make sure I could use the api at
all. It gets all the articles for the authenticated user. What’s my most
recent articles title?

library(dev.to.ol)
dev.to.ol::get_users_articles()[[1]]$title
Enter fullscreen mode Exit fullscreen mode
## Using DEVTO in .Reinviron

## [1] "Tidy Tuesday and space to learn"
Enter fullscreen mode Exit fullscreen mode

So how does this function work?

#' @title get the authenticated users articles
#' @description Provides lots of info on your users articles
#' @param key the api you have set up on DEV.TO
#' @return article stuff
#' @details if no key is supplied, will check for key named DEVTO in `.Renviron`
#' @examples
#' \dontrun{
#' if(interactive()){
#'  get_users_articles("my_api_key")
#'  }
#' }
#' @seealso
#'  \code{\link[httr]{content}},\code{\link[httr]{GET}},\code{\link[httr]{add_headers}}
#' @rdname get_users_articles
#' @export
#' @importFrom httr content GET add_headers

get_users_articles <- function(key = NA) {
  httr::content(httr::GET(url = "https://dev.to/api/articles/me",
                          httr::add_headers("api-key" =
                                              if (!is.na(key)) {
                                                key
                                              } else {
                                                message("Using DEVTO in .Renviron")
                                                Sys.getenv(x = "DEVTO")
                                              })))
}
Enter fullscreen mode Exit fullscreen mode

Very simply!

  • It uses httr to do most of the work through a GET request.
  • It allows a user to supply their own api key as an argument.
  • If the user has left that argument as the default NA, it will use the environmental variable named DEVTO. This can be set with an .Renviron file at the project or user level that looks like this:
DEVTO="obviouslynotmyrealkey"
Enter fullscreen mode Exit fullscreen mode

Motivation

So as R users, we have a great tool baked into our language: rmarkdown.
I use it for nearly everything. We also have some great tools to magnify
it’s power, such as R Notebooks, blogdown, package down and distill.
Some great R people are making the effort to put content here such as
Julia Silge (@juliasilge) and Colin Fay (@colinfay), though they are
already well established bloggers, and are publishing from their main
website through RSS. It’s a great solution for them but personally I was
looking at dev.to as a great way to not have to have a whole website.
So what do you do if you want to publish a blog, but don’t want to
actually maintain a full website? What if you also want to be able to be
part of the great dev.to community? What if you’re both of those things
and also find you have a large volume of time on your hands? You write a
package to put .Rmds onto dev.to as simply as possible.

Workflow

My current process is this:

  1. Write an Rmarkdown
  2. Render to github_document style markdown
  3. Open the markdown file I just made
  4. Copy and paste the output to the dev.to UI
  5. Fill in the meta-date
  6. Hit publish

An ideal process would be:

  1. Write an Rmarkdown
  2. Hit publish

Lets see, that’s…

removed_work <- 4/6

scales::label_percent()(removed_work)
Enter fullscreen mode Exit fullscreen mode
## [1] "67%"
Enter fullscreen mode Exit fullscreen mode

Wow, gains!

Minimum Viable Function

So, the key piece of the package is to get a function that will jump my
markdown output from my computer onto dev.to. There are lots more bits
that I should have, but that part is the most important.

#' @title Post a markdown file to dev.to
#' @description Create a new post well rendered markdown file
#' @param key Your API key, Default: NA
#' @param file The path to the file, Default: file
#' @return The response
#' @details Will look for an api key in the `.REnviron` file. Seems to check if the body is identical to a previous article and error if so with `"Body markdown has already been taken"`.
#' @examples
#' \dontrun{
#' if(interactive()){
#'  post_new_article("./articles/my_article.md")
#'  }
#' }
#' @seealso
#'  \code{\link[httr]{POST}},\code{\link[httr]{add_headers}},\code{\link[httr]{verbose}},\code{\link[httr]{content}}
#'  \code{\link[readr]{read_file}}
#' @rdname post_new_article
#' @export
#' @importFrom httr POST add_headers verbose content
#' @importFrom readr read_file

post_new_article <- function(key = NA, file = file) {

  response <- httr::POST(
    url = "https://dev.to/api/articles",
    httr::add_headers("api-key" =
                        if (!is.na(key)) {
                          key
                        } else {
                          message("Using DEVTO in .Renviron")
                          Sys.getenv(x = "DEVTO")
                        }),
    body = list(article = list(
      title = 'title',
      body_markdown = readr::read_file(file = file)
    )),
    encode = 'json',
    httr::verbose()
  )
  httr::content(response)
}
Enter fullscreen mode Exit fullscreen mode

Lots of similar things as the earlier function. Api key is all the same
code (don’t worry, when I have to write it a third time, I’ll abstract
it ;P). There are three key changes.

  1. use httr::POST instead of httr::GET because here I’m giving the api info, not requesting it.
  2. use the body argument to enclose the info I am sending the api, with a list of 1 item article which itself is a list of 2 items title and body_markdown
  3. use readr::read_file to read the markdown file I want to post into memory so it can be sent to the api

So does it work?

If you can read this, yes 🦾

Top comments (2)

Collapse
 
rmhogervorst profile image
Roel Hogervorst

Yaaaaass! Great work Dave!

Collapse
 
daveparr profile image
Dave Parr

Thanks buddy :)