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

Entry ordering - any interest? #475

Open
gausie opened this issue Jul 5, 2017 · 24 comments
Open

Entry ordering - any interest? #475

gausie opened this issue Jul 5, 2017 · 24 comments

Comments

@gausie
Copy link

gausie commented Jul 5, 2017

I'd be happy to write a PR that makes entries on the collection page draggable if there is an "order" field on that collection, and the order of the dragged elements would be reflected in said field.

This would allow most CMSs to then order entries by that order value and thus give us custom ordering.

Would such a feature likely be accepted?

@verythorough
Copy link
Contributor

Ooh, that sounds cool. One aspect to consider is how differently different site generators handle order. I would think you would want to set per collection whether the drag-to-order function is enabled, and also to specify the field name to be set by the dragging.

@erquhart
Copy link
Contributor

erquhart commented Jul 6, 2017

@gausie ordering is definitely something the CMS needs! I think the approach will be a little different - it's laid out in the designs under #179. I believe steps toward this will look something like this:

  1. Move to a list interface instead of a card interface for displaying entries
  2. Allow the fields used in the entries display (title, body, etc) to be configured per collection
  3. Implement ordering by field

This would bypass drag and drop, but would allow entries to be sorted by any field. You could then implement a custom ordering field if you wanted to set order manually.

Thoughts?

@verythorough
Copy link
Contributor

@erquhart Those improvements all sound awesome (especially #2!), but I think what @gausie is referring to is changing the field that determines post order in the site output, not in the CMS listing. For example, like we use the 'position' field in the CMS docs to set a custom order for pages.

When adding or moving a page, it's a hassle to go into the existing files, determine what position they are, choose a number that fits between them, and adjusting the surrounding page positions if there isn't enough room left between them. Being able to do this in the UI via drag-and-drop (or up/down arrow buttons) would be a huge convenience improvement.

There are a few implementation details that could be tricky, though, like how exactly to handle that number shuffling when necessary. I also wonder if it makes sense to handle the drag-and-drop ordering directly in the post view, or to put it in a different view, or perhaps a different "mode" in the same view (e.g. click an "Edit item order" button to reveal arrow buttons and make items draggable, then click "Save" commit changes and exit the mode).

@erquhart
Copy link
Contributor

erquhart commented Jul 6, 2017

Ah, good point, thanks for clarifying.

Considerations:

  • Changing the value of an entry from the collection page (including use of a separate mode) is a new concept in the CMS
  • Changing the values of multiple entries at once is also new
  • Any change could potentially require changes to every entry in the collection
  • Getting this working with the editorial workflow in an intuitive way will be tough

There's more, but I think these are the biggies. The value of the feature is apparent, but it's important to avoid adding complexity to the UI.

To answer the original question, we're definitely interested! Just need to agree on the right approach before moving forward.

@tortilaman
Copy link
Contributor

I would really appreciate a PR for this gausie. I've been doing sorting outside of the CMS since it doesn't currently have it, but within the CMS is definitely the best place for it to happen.

@rogermparent
Copy link

I've been thinking about this idea as well, and I have an idea of possible implementation

Folder collections in particular (since data ones already have sorting) have an optional "ordered: " property that enables the dragging functionality on the collection's screen. The value for this property would determine what key the numeric order will be saved as in the file-

for example: "ordered: order" would make every file in the collection have a hidden "order" key that stores the number of their position. I'm not sure how it should interact if the ordered option is specified and the same key is added into the fields.

I might try my hand at this but complex Javascript is not my forte.

@erquhart
Copy link
Contributor

erquhart commented Feb 1, 2018

@rogermparent how would you handle updating all files? For example, let's say I have fifty entries in a collection, and they all have a number value in their order field. If I change the one with value 25 to be 1, now all files that used to be values 1 through 24 have to be incremented by one, which is a whole lot of API calls. Now consider that a collection could easily have hundreds of entries, and that we may not have even fetched them all for paginated backends like GitLab.

I'm definitely not meaning to discourage you, just want to make sure we're tackling the real problem before you invest time. Ideally we could just store order info in a single file per collection and update that, but static site generators don't roll like that.

Thoughts?

@rogermparent
Copy link

rogermparent commented Feb 1, 2018

@erquhart I'm not familiar with how the GitHub API works, I didn't know it was an individual call for each file.

I suppose if you want to cut down on this you'd need an external source of ordering, which necessitates having a sort of "primary key" on the ordered files to reference them by- I think filenames are a viable candidate, as they're implicitly unique and present in all static site generators without extra work from the user.
The external file would have to be user defined so it can be accessed in templates, but the underlying data structure could be boiled down to a hash with an entry for each collection that contains an ordered array of the primary keys. Something like this can be saved and loaded to YAML, JSON, even CSV if you believe hard enough.
These files would probably be read into memory each run, and rewritten on each commit for each relevant ordered collection that's changed.

@erquhart
Copy link
Contributor

erquhart commented Feb 2, 2018

Solid response, thanks for that! This would work, but basically boils down to an extra build step where the order parameter is added to each frontmatter based on filename and a data file containing the order. Which is better than not offering this at all. Makes me wonder how much else can be done through an extra build step, and how we can make these bits easy to implement.

@Undistraction
Copy link
Contributor

Would be a big step forward just to allow for some control over the order items are displayed in. At the moment it's effectively arbitrary. Could orderOn and orderDirection fields be added to collections that would take a field and direction, and order based on the type of that field. That would at least allow entries to be ordered by date or title, or even by a manually added index field.

Guess what I'm trying to say is that displaying a collection's entries in order is separate from managing those items' order. I can see how the latter is tough, but the former feels like it should be much easier to achieve …

@erquhart
Copy link
Contributor

erquhart commented Feb 3, 2019

Agreed. There's a similar issue with more info, and the real challenge is outlined in a comment there: #54 (comment)

tl;dr: paginated endpoints are a challenge. But we could do it easily enough with GitHub.

Sent with GitHawk

@erquhart
Copy link
Contributor

erquhart commented Apr 2, 2019

Update: this doesn't have to be that difficult, actually. We're certainly not ready for a PR on it, as there still needs to be a plan of attack for the design, but I just realized we don't need to have a bunch of API calls for this to work. We would need all entries in a collection loaded, but that's already the case for other existing features, such as search.

The key will be performing the sort update in a single commit. It would touch an arbitrary number of entries in a collection, potentially all of them, but the logic for performing the change just shouldn't be that difficult. What bears consideration is how to introduce this functionality to the CMS when we have no existing method for changing multiple entries in a single commit.

@maximeduhamel
Copy link

I've been lurking around a solution for this and found my own work around for who might be interested.

1 - setup a new collection for ordering
2 - use a list widget with a relation field pointing to the collection you want to order
3 - map your entries array to your ordering list

Not ideal but it gives my client the ability to use the drag and drop feature of the list widget.

# config.yml
collections:
  - name: settings
     label: Settings
     files:
      - name: collectionOrder
        label: Collection Order
        file: src/utils/collectionOrder.md
        fields:
          - label: Collection
            name: collection
            widget: list
            fields: 
              - label: Collection Name 
                name: collectionName 
                widget: relation
                collection: collections
                searchFields: [title]
                valueField: title

          
  - name: collections
    label: Collections
    folder: src/pages/collections
    create: true
    fields: 
      - { label: Title, name: title, widget: string }
// index.js
function Page({ data }) {
  const orderingList = data.order.childMarkdownRemark.frontmatter.collection
  const collections = data.collections.edges
  return (
    <>
      {order.map(item => {
        const orderingName = item.collectionName
        return collections.map(collection => {
          if (
            collection.node.childMarkdownRemark.frontmatter.title ===
            orderingName
          ) {
            return (
              <h2 key={collection.node.id}>
                {collection.node.childMarkdownRemark.frontmatter.title}
              </h2>
            )
          } else {
            return null
          }
        })
      })}
    </>
  )
}

Not very clean but it works for me 😉Hopefully someone more clever is gonna bring this to life in a PR

@stale
Copy link

stale bot commented Oct 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@erquhart
Copy link
Contributor

erquhart commented Nov 8, 2019

stop it stale bot

@edstronaut
Copy link

Quiet around these parts, any chance of this being implemented in the near future?

@erezrokah
Copy link
Contributor

erezrokah commented Feb 24, 2020

Hi @ed-omr, we use up votes for prioritization, you can visit this link to see the most up voted issues.

@djMax
Copy link
Contributor

djMax commented May 14, 2020

I definitely agree that the cleaner solve is a separate file storing ordering information. We don't want unreadable diffs on PRs.

@theredwillow
Copy link

Not very clean but it works for me Hopefully someone more clever is gonna bring this to life in a PR

I am confused as to what this issue is supposed to pertain to. I read the original post as "There should be a way to reorder collections (i.e. the list that appears on the left of the admin page)", but your reply as "There should be a way to reorder relation widgets that have a multiple tag". Are these separate feature requests?

Reordering collections
Reordering Collections

Reordering relation widgets with multiple property
Reordering relation widgets with multiple property

I came to write up that second one as an issue, but that first one would be nice to have as well.

@d4rekanguok
Copy link
Contributor

@theredwillow That's a nice idea! I found an example of reordering selected items with react-sortable-hoc in the react-select doc so it could be a low-hanging PR if someone is interested in bringing this in.

I am confused as to what this issue is supposed to pertain to.

I think this issue is actually about sorting the order of entries inside a collection, not changing the order of collections in the sidebar.

@snimavat
Copy link

+1 : would really like to see this feature

@adambernath
Copy link

I've been lurking around a solution for this and found my own work around for who might be interested.

1 - setup a new collection for ordering 2 - use a list widget with a relation field pointing to the collection you want to order 3 - map your entries array to your ordering list

Not ideal but it gives my client the ability to use the drag and drop feature of the list widget.

# config.yml
collections:
  - name: settings
     label: Settings
     files:
      - name: collectionOrder
        label: Collection Order
        file: src/utils/collectionOrder.md
        fields:
          - label: Collection
            name: collection
            widget: list
            fields: 
              - label: Collection Name 
                name: collectionName 
                widget: relation
                collection: collections
                searchFields: [title]
                valueField: title

          
  - name: collections
    label: Collections
    folder: src/pages/collections
    create: true
    fields: 
      - { label: Title, name: title, widget: string }
// index.js
function Page({ data }) {
  const orderingList = data.order.childMarkdownRemark.frontmatter.collection
  const collections = data.collections.edges
  return (
    <>
      {order.map(item => {
        const orderingName = item.collectionName
        return collections.map(collection => {
          if (
            collection.node.childMarkdownRemark.frontmatter.title ===
            orderingName
          ) {
            return (
              <h2 key={collection.node.id}>
                {collection.node.childMarkdownRemark.frontmatter.title}
              </h2>
            )
          } else {
            return null
          }
        })
      })}
    </>
  )
}

Not very clean but it works for me 😉Hopefully someone more clever is gonna bring this to life in a PR

How can I set this up with an 11ty site? I dont have an index.js and I cant really figure out where to put it or how to reference it to make it work (the list and the sorting works fine, but it does not update the value I need - in my case it is "order_on_page" for entries located in the "src/review" folder

@adambernath
Copy link

So this is the second most requested feature for the CMS and after 7 years it is still nowhere???

@martinjagodic
Copy link
Member

Hi @adambernath the best way to move this forward is to submit a pull request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests