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

Make JSON prettifying optional #1023

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open

Conversation

Kijewski
Copy link
Collaborator

@Kijewski Kijewski commented Apr 28, 2024

This PR adds an optional argument to the |tojson filter, which controls if the serialized JSON data gets prettified or not. The arguments works the same as flask's |tojson filter, which passes the argument to python's json.dumps():

  • Omitting the argument, providing a negative integer, or None, then compact JSON data is generated.
  • Providing a non-negative integer, then this amount of ASCII spaces is used to indent the data. (Capped to 16 characters.)
  • Providing a string, then this string is used as prefix. No attempts are made to ensure that the prefix actually consists of whitespaces, because chances are, that if you provide e.g. &nsbp;, then you are doing it intentionally.

This is a breaking change, because it changes the default behavior to not prettify the data. This is done intentionally, because this is how it works in flask.


This PR is based on #1008, i.e. only the last commit is actually part of this PR.

Resolves #1019.

@Kijewski Kijewski force-pushed the pr-uglier-json branch 3 times, most recently from b06d459 to 00c7950 Compare May 1, 2024 09:19
}
}

impl AsIndent for isize {
Copy link
Owner

Choose a reason for hiding this comment

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

Does this still work if we impl for usize directly?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not if it should support jinja's API where negative value = no beautification.

askama/src/filters/json.rs Outdated Show resolved Hide resolved
value: S,
indent: I,
) -> Result<impl fmt::Display, Infallible> {
Ok(ToJson { value, indent })
Copy link
Owner

Choose a reason for hiding this comment

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

Is there reason not to store an Option<'static str> in ToJson::indent?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, the lifetimes wouldn't work.

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
to_writer_pretty(JsonWriter(f), &self.0).map_err(|_| fmt::Error)
let f = JsonWriter(f);
if let Some(indent) = self.indent.as_indent() {
Copy link
Owner

Choose a reason for hiding this comment

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

Nit: would prefer to match this, yielding out the self.indent value and doing an early return for the None case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No indentation is not the same as no beautification. A Some("") prefix still generates newlines, None does not. So both cases are entirely different. I could replace the if with a match, though.

book/src/filters.md Show resolved Hide resolved
This PR adds an optional argument to the `|tojson` filter, which
controls if the serialized JSON data gets prettified or not. The
arguments works the same as flask's [`|tojson`][flask] filter, which
passes the argument to python's [`json.dumps()`][python]:

* Omitting the argument, providing a negative integer, or `None`, then
  compact JSON data is generated.
* Providing a non-negative integer, then this amount of ASCII spaces is
  used to indent the data. (Capped to 16 characters.)
* Providing a string, then this string is used as prefix. I attempts are
  made to ensure that the prefix actually consists of whitespaces,
  because chances are, that if you provide e.g. `&nsbp;`, then you are
  doing it intentionally.

This is a breaking change, because it changes the default behavior to
not prettify the data. This is done intentionally, because this is how
it works in flask.

[flask]: https://jinja.palletsprojects.com/en/3.1.x/templates/#jinja-filters.tojson
[python]: https://docs.python.org/3/library/json.html#json.dump
@Kijewski
Copy link
Collaborator Author

Are there open questions left?

@GuillaumeGomez
Copy link
Collaborator

I'm not a big fan of this change. Wouldn't it better to have different filters for each case? Or have the current json filter unchanged and new one which allows to pass options?

@djc
Copy link
Owner

djc commented May 23, 2024

I'm not a big fan of this change. Wouldn't it better to have different filters for each case? Or have the current json filter unchanged and new one which allows to pass options?

Why aren't you a fan?

@GuillaumeGomez
Copy link
Collaborator

Mostly because most of the time, the current json filter does exactly what I want. Rust doesn't allow to have default values if you don't specify them, which is fine but not really compatible with jinja here. So in case you don't want the default filter values, you could call the other json filter (json_with_options for example) and give the options you want for this call.

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

Successfully merging this pull request may close these issues.

Allow output of not prettified JSON data
4 participants