11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.19k stars 494 forks source link

Getting url from basic file path? #1279

Open dawaltconley opened 4 years ago

dawaltconley commented 4 years ago

I have a site that lives in a subdirectory:

module.exports = eleventyConfig => {
    eleventyConfig.addPassthroughCopy('eleventy/images');

    return {
        dir: {
            input: './eleventy',
            output: './eleventy/_site',
        }
    }
}

I have a custom tag that needs to be able to figure out either:

I thought the url filter might help me do the latter, but as far as I can tell it just prepends the pathPrefix and doesn't resolve either input or output paths. {{ '/eleventy/images/foo.jpg' | url }} returns /eleventy/images/foo.jpg.

This would be simple enough if the input or output paths were accessible from within the page context or something else that a custom tag can read. As far as I know that's not the case though?

I've also tried making a collection of images by adding their file extensions to the template formats and using a directory data file—no dice on that and not sure why. Currently trying to figure this out but I'd appreciate advice if there's an easier way!

Also just to be clear, I'm trying to do this for an eleventy plugin, hence why I wouldn't necessarily know the input/output directories in the config file.

denisbrodbeck commented 4 years ago

@dawaltconley There's an easy way to get all paths for any given page: page

---
title: Blogs
layout: base
pagination:
  data: collections.blog
  size: 2
  alias: blogs
---

{{ page | log }}

Outputs:

{
  date: 2020-06-23T18:55:38.278Z,
  inputPath: './src/blog.html',
  fileSlug: 'blog',
  filePathStem: '/blog',
  url: '/blog/',
  outputPath: 'dist/blog/index.html'
}
{
  date: 2020-06-23T18:55:38.278Z,
  inputPath: './src/blog.html',
  fileSlug: 'blog',
  filePathStem: '/blog',
  url: '/blog/1/',
  outputPath: 'dist/blog/1/index.html'
}
{
  date: 2020-06-23T18:55:38.278Z,
  inputPath: './src/blog.html',
  fileSlug: 'blog',
  filePathStem: '/blog',
  url: '/blog/2/',
  outputPath: 'dist/blog/2/index.html'
}

Does this help you?

dawaltconley commented 4 years ago

In my case I'm looking to get the paths for images (or other arbitrary files), so they can't invoke page. I realize they'd have the same data, accessible from other pages, if they were tagged or part of a collection, but it doesn't seem possible to make a collection of images (not 100% sure about that but I haven't been successful at it yet).

denisbrodbeck commented 4 years ago

While you can't create a collection of raw images, you could create a list of all your images via _data files. That data will be available to your pages.

dawaltconley commented 4 years ago

I think I'd still have the same problem. I could have a _data/img.js file like this:

const globby = require('globby');

module.exports = globby.sync('./eleventy/images/**/*');

But my _data file still needs to "know" the input directory in order to get urls from the image paths. I can't think of a way to do that besides hardcoding the input dir to the data file. Might be possible by comparing process.cwd() to __dirname, though that seems hacky and wouldn't help with an 11ty plugin that lives in node_modules.

Sorry if I'm not being clear but I'm looking for a way to get input path => url or url => output path within a site that could have anything set as the input and output dirs, those being variable.

It seems like that's not possible without knowing the input / output dirs, so a plugin would need them passed along manually. In that case I might make a feature request. My first thought is exposing the input/output (and maybe data, include) dirs to pages/plugins through a global variable. I also wonder if it might be possible to make a collection out of files added through addPassthroughCopy (or add them to all) so that collection data including url and outputPath is available for them as well.

Do those make sense? I wanted to make sure I wasn't missing anything super simple before making that.

octipus commented 1 year ago

@dawaltconley Been a while since this was posted. Have you find any solution to this by any chance? I'm facing a similar issue.