How do I pretty print a hash to a Rails view?
Asked Answered
S

7

12

I have something like:

{"a":"1","b":"2","c":"3","asefw":"dfsef"}

I want to print it out in a view. What's the best way to do that?

I tried parsing it as a JSON object and using JSON.stringify, but it seems to mess up indentation.

Any advice? I don't mind a JavaScript solution.

Smiley answered 25/6, 2013 at 4:54 Comment(4)
You have a string or a is that a Hash object?Lebensraum
You're making us guess what you want, which is no fair. We can't guess because they suspended our mind-reading abilities. Can we buy a clue?Meso
Looks like you guessed anyway :) Answer lottery.Graphy
Code prettyfiers for a possible JavaScript solution: #161194Graphy
M
24

How about:

require 'json'

hash = JSON['{"a":"1","b":"2","c":"3","asefw":"dfsef"}']
puts JSON.pretty_generate(hash)

Which outputs:

{
  "a": "1",
  "b": "2",
  "c": "3",
  "asefw": "dfsef"
}

JSON.pretty_generate is more of a debugging tool than something I'd rely on when actually generating JSON to be sent to a browser. The "pretty" aspect also means "bloated" and "slower" because of the added whitespace, but it is good for diagnosing and comprehending what is in the structure so it might work well for your needs.

One thing to remember is that HTML, when rendered by a browser, has whitespace gobbled up, so whitespace runs disappear. To avoid that you have to wrap the JSON output in a <pre> block to preserve the whitespace and line-breaks. Something like this should work:

<pre>
{
  "a": "1",
  "b": "2",
  "c": "3",
  "asefw": "dfsef"
}
</pre>
Meso answered 25/6, 2013 at 5:14 Comment(3)
I disagree, if your product is an API that developers will be using then clean JSON can be a blessing for them and with gzip compression the added whitespace isn't much of a burden. Either way, would be nice to have an option to pretty print or not within your API.Premedical
We use browser plugins that allow us to see "prettitifed" JSON when we look at the output of our code while debugging, but the code itself outputs standard JSON. Between apps there is no point in sending the extra space since they don't care. Only humans do, so the browser plugins keep us happy.Meso
JSON's inherent lack of DATE support makes using JSON bad if your hash includes dates... you will not be able to tell by looking if an object is a 'real' date or a stringified date since JSON will always stringify it.Heelpiece
A
6
irb(main)> puts queried_object.pretty_inspect

From PrettyPrint, so may need to require 'pp' first for this to work.

This also works great for e.g. Rails.logger output.

Axil answered 19/9, 2016 at 17:52 Comment(0)
S
3
<%= raw JSON.pretty_generate(hash).gsub(" ","&nbsp;") %>
Sarthe answered 12/10, 2013 at 21:21 Comment(0)
L
3

If you (like I) find that the pretty_generate option built into Ruby's JSON library is not "pretty" enough, I recommend my own NeatJSON gem for your formatting.

To use it gem install neatjson and then use JSON.neat_generate instead of JSON.pretty_generate.

Like Ruby's pp it will keep objects and arrays on one line when they fit, but wrap to multiple as needed. For example:

{
  "navigation.createroute.poi":[
    {"text":"Lay in a course to the Hilton","params":{"poi":"Hilton"}},
    {"text":"Take me to the airport","params":{"poi":"airport"}},
    {"text":"Let's go to IHOP","params":{"poi":"IHOP"}},
    {"text":"Show me how to get to The Med","params":{"poi":"The Med"}},
    {"text":"Create a route to Arby's","params":{"poi":"Arby's"}},
    {
      "text":"Go to the Hilton by the Airport",
      "params":{"poi":"Hilton","location":"Airport"}
    },
    {
      "text":"Take me to the Fry's in Fresno",
      "params":{"poi":"Fry's","location":"Fresno"}
    }
  ],
  "navigation.eta":[
    {"text":"When will we get there?"},
    {"text":"When will I arrive?"},
    {"text":"What time will I get to the destination?"},
    {"text":"What time will I reach the destination?"},
    {"text":"What time will it be when I arrive?"}
  ]
}

It also supports a variety of formatting options to further customize your output. For example, how many spaces before/after colons? Before/after commas? Inside the brackets of arrays and objects? Do you want to sort the keys of your object? Do you want the colons to all be lined up?

For example, using your example Hash, you can get these different outputs, depending on what you want:

// JSON.neat_generate(o, wrap:true)
{
  "a":"1",
  "b":"2",
  "c":"3",
  "asefw":"dfsef"
}

// JSON.neat_generate o, wrap:true, aligned:true
{
  "a"    :"1",
  "b"    :"2",
  "c"    :"3",
  "asefw":"dfsef"
}

// JSON.neat_generate o, wrap:true, aligned:true, around_colon:1
{
  "a"     : "1",
  "b"     : "2",
  "c"     : "3",
  "asefw" : "dfsef"
}
Lucrecialucretia answered 16/4, 2015 at 15:54 Comment(0)
S
3

You can try the gem awesome_print works very well, and in your view write

<%= ap(your_hash, plain: true, indent: 0).html_safe %>

also, you can change the values for config the styles to hash view

Scarbrough answered 26/10, 2017 at 15:38 Comment(0)
T
2

The given response is works fine, but if you want to have prettier and more custom pretty hash, use awesome_print

require 'awesome_print'
hash = JSON['{"a":"1","b":"2","c":"3","asefw":"dfsef"}']
ap hash 

Cheers!

Thiazine answered 25/6, 2013 at 10:19 Comment(1)
awesome_print has the unfortunate flaw of forcing alignment of hashes so the => value is aligned whcih doe snot work well for nested hashes (nested hash value are actually displayed to the LEFT of the parent hash values).Heelpiece
L
1

Pretty Print Hash using pure Ruby (no gems)

I came across this thread trying to solve this problem for myself.

I had a large Hash that I wanted to make pretty, but I needed to stay in ruby hash notation instead of JSON.

This is the code + examples

  • Use pretty_generate to get a nice formatted JSON string.
  • Replace all the JSON keys with symbol: equivalent
puts JSON.pretty_generate(result)
         .gsub(/(?:\"|\')(?<key>[^"]*)(?:\"|\')(?=:)(?:\:)/) { |_|
              "#{Regexp.last_match(:key)}:"
          }

Sample JSON

{
  "extensions": {
    "heading": "extensions",
    "take": "all",
    "array_columns": [
      "name"
    ]
  },
  "tables": {
    "heading": "tables",
    "take": "all",
    "array_columns": [
      "name"
    ]
  },
  "foreign_keys": {
    "heading": "foreign_keys",
    "take": "all",
    "array_columns": [
      "name"
    ]
  },
  "all_indexes": {
    "heading": "all_indexes",
    "take": "all",
    "array_columns": [
      "name"
    ]
  },
  "keys": {
    "heading": "keys",
    "take": "all",
    "array_columns": [
      "name"
    ]
  }
}

Sample Ruby Hash

{
  extensions: {
    heading: "extensions",
    take: "all",
    array_columns: [
      "name"
    ]
  },
  tables: {
    heading: "tables",
    take: "all",
    array_columns: [
      "name"
    ]
  },
  foreign_keys: {
    heading: "foreign_keys",
    take: "all",
    array_columns: [
      "name"
    ]
  },
  all_indexes: {
    heading: "all_indexes",
    take: "all",
    array_columns: [
      "name"
    ]
  },
  keys: {
    heading: "keys",
    take: "all",
    array_columns: [
      "name"
    ]
  }
}
Lyric answered 17/7, 2021 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.