# Non-aphabetic ordering of templated dict items

**URL:** <https://forum.ansible.com/t/non-aphabetic-ordering-of-templated-dict-items/44783>\
**Category:** Get Help\
**Tags:** templating, jinja2\
**Created:** [November 4, 2025, 3:17pm UTC](https://forum.ansible.com/t/non-aphabetic-ordering-of-templated-dict-items/44783 "2025-11-04T15:17:43Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [November 4, 2025, 3:17pm UTC](https://forum.ansible.com/t/non-aphabetic-ordering-of-templated-dict-items/44783/1 "2025-11-04T15:17:43Z")

</div>

I’m pulling a bunch of dicts from an API, each of which looks something like the following after piping through `to_nice_yaml`:

```yaml
  - createdAt: '2022-01-04T16:31:35Z'
    executionOrder: Parallel
    frequency: Weekly
    frequencyDetails:
      intervals:
        interval:
        - weekDay: Monday
        - weekDay: Tuesday
        - weekDay: Wednesday
        - weekDay: Thursday
        - weekDay: Friday
      start: 02:00:00
    id: 75d85156-2e01-47a2-b3df-4a3cf7d43fed
    name: Run Flow - Weekday 2:00AM
    nextRunAt: '2025-11-04T07:00:00Z'
    priority: '50'
    state: Active
    type: Flow
    updatedAt: '2025-11-03T07:00:26Z'

```

_(These are Tableau™ job queue schedules, btw, if you’re curious. But that’s beside the point.)_  
Some of these dicts may have more or fewer attributes than shown above.

**The problem:** I want to template these dicts with a specific non-alphabetic order of top-level attributes. Particularly, `name`, `type`, and `state` should be listed first, in that order (if they exist), followed by any other existing attributes in no particular order. A bonus would be the ability to skip some attributes —`nextRunAt`, `createdAt`, and `updatedAt` for example. I don’t care about the ordering of “subordinate” attributes like the internals of `frequencyDetails` in this case.

**My Question:** Is there an elegant way of filtering or otherwise iterating over dict attributes to meet such ordering requirements? I know there are _inelegant_ ways to do it; I’m using one now, and it’s ~~xxxx~~ -ugly, full of brute force Jinja tricks that are not particularly robust when faced with dicts having missing or unexpected extra attributes. I realize the ordering doesn’t matter to machines, but humans who have to read these things would appreciate having, for example, the `name` at the top.

Suggestions?

---

<div class="post-metadata">

**Author:** ![sivel](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/sivel/32/1198_2.png) [@sivel](https://forum.ansible.com/u/sivel)\
**Post date:** [November 4, 2025, 4:45pm UTC](https://forum.ansible.com/t/non-aphabetic-ordering-of-templated-dict-items/44783/2 "2025-11-04T16:45:13Z")

</div>

I think any pure jinja implementation is going to be problematic, especially from a “wtf is this doing” perspective.

I’d recommend a custom filter. Potentially that takes a priority list. Something like:

```python
def prio_sort(v, keys=None):
    if not keys:
        prio_map = {}
    else:
        prio_map = {k: i for i, k in enumerate(keys)}

    return dict(sorted(v.items(), key=lambda k_v: prio_map.get(k_v[0], 65535)))

class FilterModule:
    def filters(self):
        return {
            'prio_sort': prio_sort,
        }

```

Then in your playbook, or wherever you use it:

```auto
things | map('prio_sort', keys=['name', 'type', 'state']) | to_nice_yaml(sort_keys=False)

```

The default for `to_nice_yaml` is `sort_keys=True` which would destroy the sorting just done, so you have to disable it.

Note that the default callback (by default) will use `json.dumps` with `sort_keys=True`, so depending on how you look at it, without the `to_nice_yaml(sort_keys=False)` it would potentially appear as though the sorting didn’t work.

---

<div class="post-metadata">

**Author:** ![utoddl](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/utoddl/32/249_2.png) [@utoddl](https://forum.ansible.com/u/utoddl)\
**Post date:** [November 4, 2025, 8:54pm UTC](https://forum.ansible.com/t/non-aphabetic-ordering-of-templated-dict-items/44783/3 "2025-11-04T20:54:15Z")

</div>

Thank you so much, @sivel. That’s exactly what I was hoping for, but my python foo is not likely to have come up with such a clean implementation. (I learned BASIC in 1978. Everything I’ve written since then looks like BASIC.)

I tweaked it a bit to fit our naming schemes, and added the bonus feature of omitting undesired keys. The final result is this:

```python
def dict_reorder(v, first_keys=None, skip_keys=[]):
    if not first_keys:
        prio_map = {}
    else:
        prio_map = {k: i for i, k in enumerate(first_keys)}

    return dict(
        sorted(
            [item for item in v.items() if item[0] not in skip_keys],
            key=lambda k_v: prio_map.get(k_v[0], 65535),
        )
    )

class FilterModule:
    def filters(self):
        return {
            'dict_reorder': dict_reorder,
        }

```

That drops right into our `local.tablinx` collection’s existing `plugins/filter/tablinx.py` file, and my invocation looks like this:

```auto
---
# ./group_vars/mw_tablinx_{{ mw_tablinx_env }}/schedules_live.yml
#
# Generated {{ now() }} by playbook mw_tablinx_utoddl_sched_2.yml.
#
# This file contains all schedules that existed in the {{ mw_tablinx_env }}
# environment at the time the playbook was run. It will be overridden
# on subsequent runs, so don't edit this file.
mw_tablinx_schedules_live_{{ mw_tablinx_env }}:
{% for sch in schedules_all | sort(attribute="state,type,name") %}
  - {{ sch | local.tablinx.dict_reorder(first_keys=['name', 'type', 'state'],
                                        skip_keys=['nextRunAt', 'createdAt', 'updatedAt'])
           | to_nice_yaml(indent=2, sort_keys=False)
           | indent(4) }}
{% endfor %} 

```

That’s still not tiny, but each bit of the Jinja does something comprehensible — which is a great improvement over the fiasco I was creating.

I am very happy! 🤩

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/ansible/original/1X/1882d9a01da5d8996a862359b0913cc568a39b84.svg) [@system](https://forum.ansible.com/u/system)\
**Post date:** [December 4, 2025, 8:54pm UTC](https://forum.ansible.com/t/non-aphabetic-ordering-of-templated-dict-items/44783/4 "2025-12-04T20:54:19Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
