Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ThemeAssetsReader which reads assets from a theme #5364

Merged
merged 9 commits into from
Sep 20, 2016

Conversation

parkr
Copy link
Member

@parkr parkr commented Sep 16, 2016

If the theme includes the 'assets' directory, it will be walked and items will be added to the site based on the normal rules of Jekyll: if there is YAML front matter, it will be added as a (convertible) Page, otherwise it will be added as a StaticFile. It will output to the assets/ directory.

[Image available, but airplane WiFi is spotty.]

  • Add basic functionality
  • Ensure jekyll new-theme looks for assets/ if present
  • Add tests
  • Update the docs

/cc @jekyll/ecosystem @benbalter @broccolini

If the theme includes the 'assets' directory, it will be walked and items will be added to the site based
on the normal rules of Jekyll: if there is YAML front matter, it will be added as a (convertible) Page,
otherwise it will be added as a StaticFile.
@@ -16,7 +16,7 @@ Lint/UnreachableCode:
Lint/UselessAccessModifier:
Enabled: false
Metrics/AbcSize:
Max: 20
Max: 21
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's cheating! 😉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😇

Copy link
Contributor

@benbalter benbalter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is awesome. So excited for this. This will hugely simplify the user experience for themes and in improve the developer experience for theme creators. Two other things to do in this PR, in my mind:

  • Update the docs
  • Update the default site to not to write a CSS file (and add that file to minima instead)

@@ -40,7 +40,11 @@ def initialize(site, base, dir, name)
@base = base
@dir = dir
@name = name
@path = site.in_source_dir(base, dir, name)
@path = if site.in_theme_dir(base) == base # we're in a theme
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain a bit more as to what's going on here?

Copy link

@ghost ghost Sep 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benbalter AFAIK, it essentially makes sure that we're normalising into the theme directory, rather than into the source directory, otherwise you might get /home/user/work/home/user/.gems/[...]/theme.html instead of /home/user/.gems/[...]/theme.html.

@parkr Have you tried this out with various symbolic links? I'm worried it might be a bit weird, depending on how base is set (I haven't checked, myself)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benbalter When you include assets/styles.scss with YAML front matter, it's a Jekyll::Page. To ensure it's read properly, we need to make sure we're looking in the theme's directory rather than your site's directory. This if says "if this Page is inside our theme directory then ensure the @path gets set properly."

module Jekyll
class ThemeAssetsReader
attr_reader :site
def initialize(site)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is copied from another reader. I don't have a personal preference and we don't have it enforced in our Rubocop config.

if Utils.has_yaml_header?(path)
append_unless_exists site.pages,
Jekyll::Page.new(site, base, dir, name)
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really elegant implementation.

@@ -43,7 +47,7 @@ def path_for(folder)
end

def realpath_for(folder)
File.realpath(Jekyll.sanitized_path(root, "_#{folder}"))
File.realpath(Jekyll.sanitized_path(root, folder.to_s))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm torn here. Do we want to pass vanilla symbols (without the _) and special case assets so that we treat all of them as named folders, rather than paths?

Copy link

@ghost ghost Sep 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're passing symbols like :_layouts, why is it called realpath_for? It's just like Site#in_theme_dir, except it takes a symbol. I think realpath_for should be an abstraction (special case :assets, for example)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Special casing is a non-starter for me in this already complicated codebase. I want a way to fetch the path on disk for a directory. If the directory starts with a _, then let's ask for it that way. It's way more direct to ask for _sass and get _sass then to ask for sass and get _sass.

@spudowiar The difference here is that this uses File.realpath which resolves symlinks. Site#in_theme_dir does not.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Would a string be a better fit stylistically then?

ThemeAssetsReader.new(@site).read
assert_file_with_relative_path @site.static_files, "assets/img/logo.png"
assert_file_with_relative_path @site.pages, "assets/style.scss"
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to test that it doesn't clobber site files?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clobber?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I have /assets/foo.js in my site, and /assets/foo.js in my theme, to confirm /assests/foo.js in the resulting site contain's the site's content, not the theme's.

private
def read_theme_asset(path)
base = site.theme.root
dir = File.dirname(path.sub("#{site.theme.root}/", ""))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do this same thing at least 2 different ways elsewhere, in the Jekyll::Layout we use the equivalent of path.sub(site.theme.root, "") and in the Jekyll::Document we use Pathutil and there are probably more ways we're doing this. 😖

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have a "relative_from" method or something but it depends on what you need. In this case, I want all directories within the theme directory without the forward slash at the beginning (e.g. assets). If you do path.sub(site.theme.root, ""), you get /assets and we can't use Pathutil because it doesn't work on Windows the way we're using it.

@@ -56,7 +56,7 @@ def setup

should "return the resolved path when a symlink & resolved path exists" do
expected = File.expand_path("./_layouts", @expected_root)
assert_equal expected, @theme.send(:path_for, :symlink)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not happy with this at all, Theme#path_for sounds like it should be an abstraction, looks like it's just a sugary version of Site#in_theme_dir

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not, as I mention above.

@parkr
Copy link
Member Author

parkr commented Sep 19, 2016

@benbalter I think we're ready for another review. I left a few comments. As for "Update the default site to not to write a CSS file (and add that file to minima instead)", this will have to be in another PR which results from a minima release. I don't think that's a good idea to do here.

Copy link
Contributor

@benbalter benbalter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One question about if we need a test to ensure the files in the site's assets folder are given preference over files in the theme's asset folder, otherwise, LGTM. Nice work. Glad this wasn't too crazy to implement.

@parkr
Copy link
Member Author

parkr commented Sep 20, 2016

One question about if we need a test to ensure the files in the site's assets folder are given preference over files in the theme's asset folder

Done in 29d8fee.

* master:
  Update history to reflect merge of #5381 [ci skip]
  Update history to reflect merge of #5383 [ci skip]
  run features on windows
  Appease Rubocop
  Update history to reflect merge of #5372 [ci skip]
  Add missing period to sentence in first paragraph.
@parkr
Copy link
Member Author

parkr commented Sep 20, 2016

@jekyllbot: merge +minor

@jekyllbot jekyllbot merged commit 3a45bf7 into master Sep 20, 2016
@jekyllbot jekyllbot deleted the themes-asset-folder branch September 20, 2016 20:40
@parkr parkr added this to the 3.3 milestone Sep 20, 2016
jekyllbot added a commit that referenced this pull request Sep 20, 2016
@jekyll jekyll locked and limited conversation to collaborators Jul 11, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants