8000 Allow filters to sort & select based on subvalues by gnuletik · Pull Request #5622 · jekyll/jekyll · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Allow filters to sort & select based on subvalues #5622

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

Merged
merged 9 commits into from
Jun 14, 2017
Merged

Allow filters to sort & select based on subvalues #5622

merged 9 commits into from
Jun 14, 2017

Conversation

gnuletik
Copy link
Contributor
@gnuletik gnuletik commented Dec 3, 2016

Hi,

I was trying to sort a collections using the sort filter like this {% assign collec = site.my_collection | sort 'header.year' %} but the subvalue wasn't working, so I made a quick fix.

Maybe I should do the same thing for item.data[property.to_s] and item[property.to_s] making a new method.

What do you think about it ?
Thanks !

@ashmaroli
Copy link
Member

@gnuletik can also add to the test/test_filters.rb to check if this works as intended, especially with any future changes..

@gnuletik
Copy link
Contributor Author

Hi ! Any news on this ?

@pathawks
Copy link
Member

/cc: @jekyll/build

Copy link
Member
@parkr parkr left a comment

Choose a reason for hiding this comment

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

Looks good! Let's use .reduce to clean things up.

property.to_s.split(".").each do |attr|
res = res[attr]
end
res
elsif item.respond_to?(:data)
item.data[property.to_s]
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't that also need to happen here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's what I was wondering in my first topic, but isn't it used for data files ? If yes subvalues may already be supported

Copy link
Member

Choose a reason for hiding this comment

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

You could test it out (via CI and manually) to confirm..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ashmaroli You are right, it wasn't working for data files.

Here are my tests:
_data/test/test.json

{
	"array": [
		{"header": { "year": 2001 }},
		{"header": { "year": 2004 }},
		{"header": { "year": 2006 }},
		{"header": { "year": 1972 }},
		{"header": { "year": 2010 }},
		{"header": { "year": 1990 }},
		{"header": { "year": 12 }},
		{"header": { "year": 0 }},
		{"header": { "year": 1996 }}
	]
}

index.html

---
---
{% assign test = site.data.test.array | sort: 'header.year' %}
{{ test }}
{% for i in test %}
	{{ i.header.year  }}
{% endfor %}

Commands :

$ jekyll -v
jekyll 3.4.3
$ jekyll build && cat _site/index.html
Configuration file: none
            Source: /tmp/test-site
       Destination: /tmp/test-site/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 0.01 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

{"header"=>{"year"=>2001}}{"header"=>{"year"=>2004}}{"header"=>{"year"=>2006}}{"header"=>{"year"=>1972}}{"header"=>{"year"=>2010}}{"header"=>{"year"=>1990}}{"header"=>{"year"=>12}}{"header"=>{"year"=>0}}{"header"=>{"year"=>1996}}

        2001

        2004

        2006

        1972

        2010

        1990

        12

        0

        1996

With the last commit :

$ ../jekyll/exe/jekyll build && cat _site/index.html
C
10000
onfiguration file: none
            Source: /tmp/test-site
       Destination: /tmp/test-site/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
                    done in 0.009 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

{"header"=>{"year"=>0}}{"header"=>{"year"=>12}}{"header"=>{"year"=>1972}}{"header"=>{"year"=>1990}}{"header"=>{"year"=>1996}}{"header"=>{"year"=>2001}}{"header"=>{"year"=>2004}}{"header"=>{"year"=>2006}}{"header"=>{"year"=>2010}}

        0

        12

        1972

        1990

        1996

        2001

        2004

        2006

        2010

Copy link
Member

Choose a reason for hiding this comment

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

That's great! Could you add a similar test to our test-suite as well? Thanks 🙂

Copy link
Contributor Author
@gnuletik gnuletik May 17, 2017

Choose a reason for hiding this comment

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

Yeah I would like to but in the test/test_filters.rb file I can't figure out how can I give the input as an object responding to data.

I looked for other filters test and there is no filters testing for data inputs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ashmaroli Also, I'm trying to find in which use case the else condition is being called (where the input does not have .data or .to_liquid) but I can't find.

May it be possible to identify tests going though thanks to code climate ? I didn't find how I can achieve that.

Thanks !

property.to_s.split(".").each do |attr|
res = res[attr]
end
res
Copy link
Member

Choose a reason for hiding this comment

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

This code can be cleaned up:

property.to_s.split(".").reduce(item.to_liquid) { |res, prop| res[prop] }

Copy link
Member

Choose a reason for hiding this comment

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

additionally, what is res? Is there a better name we could give it? I'm also not a giant fan of abbreviations, and would prefer to see property used in place of prop instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm would use subvalue and attribute instead of res and prop but I can't because the line can't exceed 90 characters.

I also can't make it multine like this because it's not allowed in the rules.

        property.to_s.split(".").reduce(item.to_liquid) { |val, attr|
          val[attr]
        }

Copy link
Member

Choose a reason for hiding this comment

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

split_properties = property.to_s.split(".")
split_properties.reduce(item.to_liquid) do |subvalue, attribute|
  subvalue[attribute]
end

should be good enough for rubocop

Copy link
Contributor Author
@gnuletik gnuletik May 17, 2017

Choose a reason for hiding this comment

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

Yes it is :)
I even removed split_properties = property.to_s.split(".") as rubocop allows 90 characters.
Thanks !

@ashmaroli
Copy link
Member

@gnuletik I ran a couple of tests locally using your sample json file and page, above against both manually creating a test site and the following:

      should "return sorted by subproperty data array" do
        site = fixture_site
        site.data.merge!({
          "array" => [
            { "a" => { "b" => 2 } },
            { "a" => { "b" => 1 } },
            { "a" => { "b" => 3 } },
          ]
        })
        assert_equal(
          [
            { "a" => { "b" => 1 } },
            { "a" => { "b" => 2 } },
            { "a" => { "b" => 3 } },
          ], @filter.sort(site.data["array"], "a.b")
        )
      end
    end

My inference is that you don't have to patch item.respond_to?(:data) for this feature to work with data files

@pathawks @parkr pinging you guys if could confirm my finding when possible

@gnuletik
Copy link
Contributor Author
gnuletik commented May 18, 2017

@ashmaroli I did the tests too and your're right : patching item.respond_to?(:data) doesn't implement this feature for data files. I reverted the changes. So I don't know when it's being used.

@gnuletik
Copy link
Contributor Author

So, is this version okay ?

@gnuletik
Copy link
Contributor Author

up

@parkr parkr changed the title Accessing subvalue from filters Allow filters to sort & select based on subvalues Jun 14, 2017
@parkr
Copy link
Member
parkr commented Jun 14, 2017

@jekyllbot: merge +minor

@jekyllbot jekyllbot merged commit e031ac9 into jekyll:master Jun 14, 2017
jekyllbot added a commit that referenced this pull request Jun 14, 2017
@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.

6 participants
0