Code Monkey home page Code Monkey logo

Comments (24)

yihui avatar yihui commented on July 28, 2024 15

As @maxheld83 pointed out, I'd also recommend using the static/ folder. Everything under static/ will be copied to public/, so you can reference the image using /path/to/image.png (note the leading slash, without which the path will be relative) if this image is originally at static/path/to/image.png.

A relative path like @pssguy pointed out also works, but it is dependent on the location of the .html file, i.e. you have to count how many levels you have to go up (i.e. how many ../) from the directory of the .html file to find the image.

from blogdown.

apreshill avatar apreshill commented on July 28, 2024 7

Hi @missaugustina,

Messaged you on twitter too. As suggested in this thread, my recommendation is put all static files, like data files (.csv, .RDS, etc.) and images (.jpeg, .gif, .png) into the /static folder.

Images

For images referenced in a post, we discussed how to reference a file in that folder in the blogdown demo site and in the book.

You can also make files within the /static subfolder structure, like we did on the blogdown demo site. I also did this for our RLadies site.

The short story is that if you are in a post, Hugo looks for all external files in the /static folder by default. So if your image is called "piggie.png", that file should be in the /static folder for Hugo to find it. If you instead want to put "piggie.png" in the /static folder but inside of a subfolder called "images" (so /static/images), you would reference that file in your post with: /images/piggie.png (because it starts at /static as the root).

Data files

Now data files are a bit trickier, because your .Rmd post looks first in the same folder that the .Rmd file is, so it looks in /content/post first. Mara had a good answer here on this topic. There are 4 ways:

  1. Put your data files in /content/post and it will just work
  2. Put your data in /static instead. To reference that kind of file in an R chunk, you'll need to do ../../static.
  3. You can use the here package to build the file path (see below for example)
  4. You can upload your file to your git repo then use the raw url from GitHub to read in

Your two examples

readRDS("myfile.RDS") <-- what path can I use that both RStudio and Hugo/blogdown will find and not error?

Answer:

  • if "myfile.RDS" is in /static, the path you use in the post is ../../static/myfile.RDS
  • if "myfile.RDS" is in /static/data, the path you use in the post is ../../static/data/myfile.RDS
  • if using here package:
library(here)
libarary(readr)
mydata <- read_csv(here("static/data/", "myfile.csv"))
# or
myfile <- here("static/data/", "myfile.csv")
mydata <- read_csv(myfile)
  • if using a GitHub raw url:
mydata <- read_csv("https://gist.githubusercontent.com/kylebgorman/77ce12c9167554ade560af9d34565c11/raw/c5d653fb146821ecd96a9aa085263c3f17480dd5/McFarlaneEtAl_MazeData-Deidentified.csv")
# or
mylink <- "https://gist.githubusercontent.com/kylebgorman/77ce12c9167554ade560af9d34565c11/raw/c5d653fb146821ecd96a9aa085263c3f17480dd5/McFarlaneEtAl_MazeData-Deidentified.csv"
mydata <- read_csv(mylink)

my image <-- what path can I use that both RStudio and Hugo/blogdown will find and render correctly?

Answer:

  • if "myimage.png" is in /static, the path you use in the post is myimage.png
  • if "myimage.png" is in /static/images, the path you use in the post is /images/myimage.png

Does that help? Let me know 😍
If it does, I'll add a new post to the blogdown demo site πŸ‘

from blogdown.

maxheld83 avatar maxheld83 commented on July 28, 2024 6

just store the image in static/img/pic1.png and then include it by ![My picture](img/pic1.png).
Works for me.
Notice though that R / blogdown never touch this; that's just basic markdown/HUGO.
So there's no special blogdown sauce for doing this AFAIK.

(Ps.: the img folder is not technically necessary; just seems to be a HUGO convention.)

from blogdown.

yihui avatar yihui commented on July 28, 2024 5

I have finished the relevant documentation for this issue:

from blogdown.

janeshdev avatar janeshdev commented on July 28, 2024 3

@pssguy Thanks for the suggestion.
@yihui Yes that leading / (leading slash) did the trick. Now, the image is displayed properly.

from blogdown.

skadauke avatar skadauke commented on July 28, 2024 3

The problem I have with using the static/ folder is that I like to see images displayed in the RStudio Editor while I am writing. For example, say I'm working on a post that includes the following image reference:

![](image.png)

And the directory structure is:

content/post/2017-06-06-imagetest.Rmd
content/post/image.png

Then RStudio will display the image without giving me an annoying error that the image cannot be found. However, with the default settings, blogdown + Hugo will then create:

public/2017/06/06/imagetest/index.html
public/post/image.png

Since the index.html file links to image.png but that image is no longer in the same folder, the web browser will show a broken image link.

It seems like what should happen is for Hugo to copy over image.png to public/2017/06/06/imagetest/ or else, update the reference, but neither happens.

I ended up solving this issue by making the following changes in config.toml:

uglyurls = true
#[permalinks]
# post = "/:year/:month/:day/:slug/"

Now blogdown/hugo creates:

public/post/imagetest.html
public/post/image.png

And everything works. I hope this helps anyone else struggling with getting images to work... and please let me know if there is a better way to do this!

from blogdown.

pssguy avatar pssguy commented on July 28, 2024 2

@janeshedev I had problems with this too some time ago and meant to get back to it. As a hack, I found that creating an img folder in public and then putting images in there and referencing this way worked

<img src="../../img/mypic.png" alt="" />

But I think this is likely to cause more problems so I'm not recommending it

from blogdown.

dracodoc avatar dracodoc commented on July 28, 2024 2

@yihui
After reading the discussion above, I'm wondering if it's possible to make things work as expected instead of ask users to understand the complex steps required now.

A RMarkdown should work in local rendering and rendered website in same way.

  • if we need to modify the document, manipulate folders, paths when converting a local rmd to blog, that's not optimal.
  • that will need more plumbing work in blogdown side to make things looks smooth for users.

What's the best way to do that plumbing work?

  • I'll suggest to make the assumption that each rmd can have one companion folder. For example report_1.rmd have a report_1_src_files folder in same level.
    • Organizing files related to a report is a complex topic, some users may have files in other folders. To make things under control we can assume it's reasonable to ask users to copy all files needed into one folder in same level with report at least for using blogdown.
  • User should just write the rmd like before, and rstudio can preview the image normally. The rmd can be knitted normally.
  • blogdown need to know that companion folder belong to that post first before it can deal with it properly. This can be done in several ways:
    • add an entry in rmd yaml header. This is simple and clear.
    • use some folder naming convention. I don't think this is a good idea. something like report_1_files can conflict with generated folder/files.
    • scan the rmd for local reference and determine the folder belong to the rmd. This approach have the advantage that user can use multiple folders. But I think this make things too complex.
      I think the yaml header method is simplest and best.
  • With the companion folder knowledge, blogdown can do the additional steps needed:
    • copy the folder to static. I'm not sure whether we should add more level for organization, but at least it should not be put in report_1_files folder to avoid conflict with generated files.
    • modify the links in rmd before rendering. I assume there are some preprocess to rmd and we can update links in this step, maybe save to a temporary file.
      • previously user should use relative path for files in companion folder, now they need to be either
        • relative path, with proper levels jumped
        • absolute path, this can be done with just adding / in beginning, if there is no subpath in website involved. I think blogdown should know about the subpath and can add it when needed.

If you think this direction is good, I'll try to look at the code and get a PR when I got more time.

from blogdown.

jimingshuo avatar jimingshuo commented on July 28, 2024 1

I started to use Blogdown two days ago, and this was exactly an issue bothered me when I tried to create my first post.

After several trials, I realize that Yihui and most of the people use Mac OS, while I am using Windows 10. And I believe Blogdown behaves differently in Windows OS. When I create a new post by using "Addins"->"New Post", Blogdown creates the *.RMD file in "../content/post" instead of "../static/post" folder, while ".." is my project folder. Under the "../static/post" folder, it actually contains the folder "2015-07-23-r-rmarkdown_files", which should be copied or compiled by RMarkdown during the installation of the package.

Once I save my images in "../content/post/img", then those images are available in my post.

image

from blogdown.

gadenbuie avatar gadenbuie commented on July 28, 2024 1

Version 0.6 of blogdown will include a new "Insert Image" RStudio Addin that makes it much easier to add images to blog posts. The feature is already available in the GitHub version of blogdown -- which you can install via devtools::install_github("rstudio/blogdown").

The addin was contributed by @lcolladotor and there is a nice introduction to it on his blog.

Hopefully this feature will help reduce the friction around the content and static directories. @apreshill would this be a good feature to highlight or add to the blogdown demo site?

from blogdown.

yihui avatar yihui commented on July 28, 2024 1

Oh @skadauke you have come here. Apparently I didn't remember your name at rstudio::conf when you mentioned the idea to me, but I did remember your idea and mentioned it when @lcolladotor implemented the "Insert Image" addin: #272 (comment)

from blogdown.

janeshdev avatar janeshdev commented on July 28, 2024

@maxheld83 Thank you for your response. I did what you proposed. But I am still not being able to see the image. Btw I am using wamp server to view my blog generated from blogdown.

from blogdown.

yihui avatar yihui commented on July 28, 2024

Well, using an absolute path also has its drawback. For example, it works if you publish the website to example.com, but it won't work if you publish to a subdirectory like example.com/foo/ (in this case, the absolute path has to be /foo/path/to/image.png). Relative paths works everywhere, but the problem is as I mentioned -- you need to count how many levels you have to go up (if your .html is rendered to a different folder in the future, you may have to adjust the number of ../). Either way has its pros and cons. I'll just let you decide which way you want to go.

from blogdown.

janeshdev avatar janeshdev commented on July 28, 2024

Thanks for pointing out the advantages / disadvantages of both the approaches.

from blogdown.

yihui avatar yihui commented on July 28, 2024

@skadauke That is the best way if you do not use the Serve Site addin to preview your site in the RStudio Viewer but want to preview images right in the source editor.

from blogdown.

skadauke avatar skadauke commented on July 28, 2024

@yihui I guess I want both :)

from blogdown.

taraskaduk avatar taraskaduk commented on July 28, 2024

@yihui is there a way to make blogdown copy objects from /content to /static?
In my /content folder, I store my posts in R projects in folders, so that the .Rmd file and all supporting data and files are stored in one place. Here, I'll also store any external pictures that aren't generated by my code.

What I understand now is that in order to include an external picture into my post, I need to do either one of 2 things:

  1. manually copy the picture into the /static folder
  2. play with the relative path, jumping up one step and them digging down again to exit the /static folder and go back to the /content folder.

Any better solutions you might suggest?

from blogdown.

missaugustina avatar missaugustina commented on July 28, 2024

I'm going to second the issues here. I've just spent over 3 hours trying to get this to work. I'm including files in my Rmd so I can generate plots as well as external images. The files fail if they can't find the path from within RStudio but once I get those to pass, the generated paths are preventing things from showing up. The docs aren't clear, or maybe they are to someone who is not trying to do this at 1am... but that's usually my baseline.

Here's my use case:

readRDS("myfile.RDS") <-- what path can I use that both RStudio and Hugo/blogdown will find and not error?

my image <-- what path can I use that both RStudio and Hugo/blogdown will find and render correctly?

from blogdown.

dracodoc avatar dracodoc commented on July 28, 2024

Hugo 0.32 start to support page bundles, which can include various assets with post together. However it's quite complex, and I don't think it's easy to use or familiar for Rmd workflow.

One simple hack could be just automate the manual tasks as much as possible:

  • write rmd in a draft folder, save assets files in a folder with same name of rmd (so there is no need to specify this folder), use relative path in rmd. Everything should work and can be previewed.
  • use script to copy the asset folder to static, and change the relative link in rmd to absolute link, copy rmd to content/post. This should ensure the post have correct links.

from blogdown.

dracodoc avatar dracodoc commented on July 28, 2024

That will be great for the workflow of creating new post from scratch inside RStudio. Though I feel it's kind of extra effort because inserting an image in markdown format used to simple and don't need a GUI.

blogdown is limited by how hugo doing things, the page bundle feature in hugo looks too complex for me too.

from blogdown.

skadauke avatar skadauke commented on July 28, 2024

@gadenbuie I'm wondering if it's such a great idea to create functionality for blogdown only that should really be universal to all of R Markdown. At rstudio::conf I had briefly spoked to @yihui and suggested a feature that would allow dragging+dropping an image file or pasting an image from clipboard directly into the RStudio editor - and RStudio would automatically place a copy of the image in the correct place and insert the code to link to the image.

from blogdown.

dracodoc avatar dracodoc commented on July 28, 2024

This is the script I used to convert existing rmd:

  • assume asset folder is same name with rmd file name. don't use white space in file name
  • use / in path
  • I need to use absolute path in parameters because the site is not top level in my project, and servr have to change working directory to the site, so better use absolute path
  • this function will modify the asset folder link and save new rmd to post folder, copy asset folder to static
# it's better to use - or _ in file name instead of white space.
# press tab in link to refresh the rstudio preview
# need absoluate path because servr changed current working directory.
process_rmd <- function(rmd_path, site_path = ".") {
  # assume asset folder has same name of rmd name
  file_name <- basename(rmd_path)
  asset_folder <- substr(file_name, 1, nchar(file_name) - 4)
  # change relative path of assets folder to absolute path
  # to deal with encoding, there are some internal functions. just assume utf 8 here.
  # input_lines <- rmarkdown:::read_lines_utf8(rmd_path, getOption("encoding"))
  input_lines <- readLines(rmd_path)
  input_lines <- gsub(paste0("](", asset_folder, "/"), 
                      paste0("](/", asset_folder, "/"),
                      input_lines, fixed = TRUE)
  post_path <- file.path(site_path, "content", "post", file_name)
  writeLines(input_lines, post_path)
  # copy asset folder to static/. also assume using / instead of \
  asset_path <- file.path(dirname(rmd_path), asset_folder)
  static_path <- file.path(site_path, "static")
  file.copy(asset_path, static_path, recursive = TRUE)
}

from blogdown.

jimingshuo avatar jimingshuo commented on July 28, 2024

I think the best way to fix this is to update RMarkdown code, just find out where it says a new post should be saved in "contents" folder, and change that to "static", to keep the consistency for all OS.

from blogdown.

cdriveraus avatar cdriveraus commented on July 28, 2024

I am struggling with this behaviour... I have R code that renders complex math (mathjax doesn't handle well) to pdf, trims the pdf and saves to png, all in the working directory. This works fine if I knit the file locally, but fails when using serve site.

I have worked around this by creating the folder specified by slug, and within the Rmd pointing all outputs to that, but it seems rather inelegant...

from blogdown.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.