Make many files avaliable to download

I am new to web development and have recently started a project in Hugo. The project is a documentation page where I will upload materials from my program in university (lecture notes, old exams…).

I have created the page and now I want to upload the files and I have a few questions regarding this.

I am looking to create a shortcode in order to access the pdfs. However, I dont know how I should go about this.

Is it possible to somehow connect and get the files from a file hosting site, for example google drive, where I upload the files and the shortcode can access the files from there?

Or is it good to have all the contents from the course inside the “project” and access it from there? There are a lot of files and pdfs, and the number will increase since I am planning to do this with other uni programs aswell.

Im very new to this and looking for any directions to go about this. I have not even been able to access a single file, I have tried ref and relref with no success…

If you are asking how to add links to external resources: you can look up what the markdown syntax is for links.

Whether you have your files inside your project or not is up to you. Keep in mind file and project size limitations of whichever git/hosting solution you use.

I would suggest you go through Recommended Reading Reference and start with a small Hello World project first.

1 Like

You’d need direct URLs to your files, that is, the files should be directly served. Most file hosting websites don’t support this. They would give you a link to their page, and the user will then have to click on a download button on that page to access the file. If that works for your case, you’re good to go. However, it won’t work if you plan to display the PDFs within the browser and on your website itself. From what I know, only Dropbox allows you to get static links to your file (you have to edit the query of the link the website gives you from dl=0 to raw=1 or something like that). However, with Dropbox free account, you are limited to 2 GB storage.

I am considering you’re referring to your website by using the word ‘project’. If you want to store all PDFs on your website itself, you’d need a good server to serve those files. Depending on the size of each PDF and the number of PDFs and the number of visitors you expect to get on your website, you’d have to estimate which server can give you that much storage and bandwidth for a price you can afford. If you plan to host on services like Netlify and Vercel, you get more or less unlimited storage but 100 GB bandwidth/month for free. It’s more than enough for most users, but, you need to make sure to estimate it.

Also, if you plan to let users download multiple files at once, browsers might block that attempt and you might need some server side zipping (much like how Google Drive zips your files when you try to download an entire folder).

So, it really depends how you want to treat the PDFs. From your post, you said, you’re making a shortcode for the PDFs, so, I assumed that you want to show it in browsers (and let users download it as well). If that’s the case, you might want to use a JavaScript library to show a consistent UI across browsers to display your PDFs, because if you use something like <embed>, each browser will display the PDF in its own native way and it might not work on mobile devices.

1 Like

Thank you, I will look into it. I have started a website from a template with very basic html knowledge. I have reached the step of adding the links. What I understood was that I can use ref and relref to reference to a file. For example I have tried:

{{< relref “/static/Folder1/File1.pdf” >}}

while trying to reference it from a /content/docs/Something.md but I get the error:

[en] REF_NOT_FOUND: Ref "/static/Folder1/File1.pdf": "C:\Hugo\mysite\content\docs\Something.md:11:1": page not found
Rebuild failed:

Logged 1 error(s)

I am thinking it has to do with where I store my file, but I have tried having it in the same folder where the .md file is aswell.

Maybe you can help me with this?

Thank you very much, it was very informative.

I was wondering this aswell because you mentioned hosting. I am currently using a web hotel with cPanel. I was completely clueless to services like Netlify, node, Vercel. I have read that transferring a server to these services is a pain, but I have not seen much on how someone with for example cPanel will use Hugo? Do you know any resources that may help with this, or maybe you know?

Very thankful for all these answers as they have helped me a lot

You don’t need relRef for a simple link. If you store file at /static/Folder1/File1.pdf, simply link it in your markdown using [text to link](/Folder1/File1.pdf).

I’d say, there services are way easier than using cPanel for a static website. Since you’re using Hugo, you might not be needing any backend, database, etc., all you need to serve is static HTML, CSS, JS (+ images, and other media). So, if and only if that’s the case, it’s possible to make a switch. If you need even 1 line of PHP, you’re out of luck.

About moving from cPanel to Netlify (or Vercel), it doesn’t really need anything much to ‘move’ as such. Once you build your website locally using hugo command, you can just drag and drop the folder to your Netlify dashboard or if you are familiar with Git, you can just push your changes to Git, connect the repository once to Netlify and every change you push is automatically deployed.

1 Like

Once again, thank you for a very informative post.

I have one more question if that is fine;
I have read a little bit about the readDir function and I don’t really understand how it works. Is it possible, or is there a function that can take all files in a folder (pdfs) and create a list of them?

For example, I have in /static/Folder1/Files1-x where x is the amount of files 1 to x. To then use a function that takes all of these files and creates a list of them?

I am sorry for these trivial questions but I am trying to learn it as I am using it, and the answers here help me very much.

Ahh, you’ve reached an area in which I’m not so skilled. But, from what I know, you can do what you want only if you organise your posts in folders, that is…

.
└── content/
    └── post1/
        ├── assets/
        │   ├── foo.pdf
        │   └── bar.pdf
        └── index.md

then you can do something like:

{{ delimit (.Resources.Match "assets/*.pdf") ", " }}

which will return assets/foo.pdf, assets/bar.pdf. I’m not sure how you can convert this to a list, but, there must be a way. Maybe, someone else can educate us on this.

1 Like

@boof, you might have some good news. I have figured out a ‘hacky’ way to get it work. I am calling it hacky because I’m not sure if it’s the best or the most optimal way, but, it does the trick.

You can use this in your layouts/_default/single.html:

{{ $allPDFs := .Resources.Match "*.pdf" }}

	{{ range $k:= (seq 0 (sub (len $allPDFs) 1)) }}

		<a href = "{{ index $allPDFs $k }}">{{ index $allPDFs $k }}</a><br>

	{{ end }}

This will create a link on a new line for each of the files. This will work as is if you store your files like:

└── content/
    └── post1/
        ├── foo.pdf
        ├── bar.pdf
        └── index.md

If you organise it like the way I mentioned before, that is,all the PDFs in the ‘assets’ folder of the post, you’d get links like:

assets/foo.pdf and you’d probably not want that. So, with the code and the directory structure I have posted currently, you’d get a link on each line with the name of the PDF file. I have tried this with the images in my website, and just modified the extension while posting it here, so, it should work for your PDFs.

Thank you for all of this.

I dont really understand how to use it. I have copied it to my single.html file and organized some files as you said. But how do I then actually call on the code?

The code that goes in single.html actually works like this:

{{ $allPDFs := .Resources.Match "*.pdf" }} matches and stores all files with the extension .pdf that are present in the same folder as the index.md for the post as in array inside the variable allPDFS.

The part:

{{ range $k:= (seq 0 (sub (len $allPDFs) 1)) }}

    <a href = "{{ index $allPDFs $k }}">{{ index $allPDFs $k }}</a><br>

{{ end }}

is looping over all the elements of the array and rendering a <a> tag with a link for each of the PDF. You can change the look and style of this part by editing the line: <a href = "{{ index $allPDFs $k }}">{{ index $allPDFs $k }}</a><br>

It works as follows:

The range function defines a variable k and loops over a sequence that starts from 0 and ends at the one less than length of the array (allPDFs) (because arrays start at 0). The variable k is the number that is used further.

Then, the function index $allPDFs $k is actually choosing the specific element from the array, 0 being the first one.

After you add it to your single.html and organize, it’s already executed when you actually run the server or make the production build. You don’t need to do anything else. It will only be visible on the content pages (that’s what’s defined in single.html. So, your URL where the links might be displayed is: localhost:1313/post1/. Is it not visible there?

If would help if you can send a small reproducible example to show what exactly you’re doing so we can see if you’ve made a mistake somewhere or understand your use case better.

1 Like

I think it’s something about the template I’m using or something about my first “post” being in /docs/ but I am very unsure. How would I go about to show an example? Should I upload the project to github maybe?

Thank you very much for your patience, you have been extremely helpful

Yeah, that can work, or you can share a zip of the folder using some could drive. Any way would do.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.