Skip to content

Commit

Permalink
Add Content#relative_path which returns a file's relative path with…
Browse files Browse the repository at this point in the history
…in its collection (#7)
  • Loading branch information
benpickles authored Nov 19, 2024
1 parent 324c24e commit 1052001
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 3 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
# CHANGELOG

## Unreleased

- Add `Content#relative_path` which returns a file's relative path within its collection.

## Version 0.2.0 - 2024-10-13

- Add support for a content instance knowing its own `#slug` - its relative path within its collection:
- Add support for a content instance knowing its own `#slug` - its extension-less relative path within its collection:

```ruby
Page = Decant.define(dir: 'content', ext: 'md')
Expand Down
11 changes: 10 additions & 1 deletion lib/decant/collection.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,22 @@ def glob(pattern)
dir.glob("#{pattern}#{ext}").select { |path| path.file? }
end

# The relative path of +path+ within {#dir}.
#
# @param path [Pathname]
#
# @return [String]
def relative_path_for(path)
path.relative_path_from(dir).to_s
end

# The extension-less relative path of +path+ within {#dir}.
#
# @param path [Pathname]
#
# @return [String]
def slug_for(path)
relative_path = path.relative_path_from(dir).to_s
relative_path = relative_path_for(path)

# The collection has no configured extension, files are identified by
# their full (relative) path so there's no extension to remove.
Expand Down
14 changes: 14 additions & 0 deletions lib/decant/content.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ def frontmatter(*attrs)
end
end

# The relative path of the file within its collection.
#
# @example
# Page = Decant.define(dir: 'content', ext: 'md')
#
# page = Page.find('features/slugs')
# page.path.expand_path # => "/Users/dave/my-website/content/features/slugs.md"
# page.relative_path # => "features/slugs.md"
#
# @return [String]
def relative_path
self.class.collection.relative_path_for(path)
end

# The extension-less relative path of the file within its collection.
#
# @example
Expand Down
27 changes: 27 additions & 0 deletions spec/decant/collection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,33 @@
end
end

context '#relative_path_for' do
let(:collection) { described_class.new(dir: dir, ext: ext) }
let(:dir) { Pathname.new('/tmp/not-a-real-path') }

def relative_path_for(path)
collection.relative_path_for(dir.join(path))
end

context 'when #ext is not defined' do
let(:ext) { nil }

it 'includes the extension' do
expect(relative_path_for('foo.txt')).to eql('foo.txt')
expect(relative_path_for('foo/bar.txt')).to eql('foo/bar.txt')
end
end

context 'when #ext is defined' do
let(:ext) { '.md' }

it 'returns the relative path' do
expect(relative_path_for('foo.md')).to eql('foo.md')
expect(relative_path_for('foo/bar.md')).to eql('foo/bar.md')
end
end
end

context '#slug_for' do
let(:collection) { described_class.new(dir: dir, ext: ext) }
let(:dir) { Pathname.new('/tmp/not-a-real-path') }
Expand Down
12 changes: 11 additions & 1 deletion spec/decant/content_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,20 @@
end
end

describe '#relative_path' do
let(:klass) { Decant.define(dir: tmpdir, ext: '.md') }

it 'is the relative path within its collection' do
file('foo/bar.md')
instance = klass.find('foo/*')
expect(instance.relative_path).to eql('foo/bar.md')
end
end

describe '#slug' do
let(:klass) { Decant.define(dir: tmpdir, ext: '.md') }

it 'is the relative path within its collection excluding the extension' do
it 'is the extension-less relative path within its collection' do
file('foo/bar.md')
instance = klass.find('foo/*')
expect(instance.slug).to eql('foo/bar')
Expand Down

0 comments on commit 1052001

Please sign in to comment.