Reputation: 6232
We do use .to_yaml
on ActiveRecord to dump some values of a record in to a .yml
file for backup reasons.
Those files are stored into a repository as those backup data is part of defaults for setup new systems.
Example:
---
guid: dbYSoCvkzq9z5ZFyRxy0lE
name: bookmarklisting
template: |-
<div class="template">
<tpl for=".">
<div class="x-like-menu-item pointer selection {[xindex%2==0 ? "even" : "odd"]}">
{[Ext.String.htmlEncode(values.topic||values.title||t("infobase.missing_topic"))]}
</div>
</tpl>
</div>
config: "{ foo:true }"
deactivated: false
created_at: !ruby/object:ActiveSupport::TimeWithZone
utc: 2012-03-01 13:31:47.296000000 Z
zone: &1 !ruby/object:ActiveSupport::TimeZone
name: Europe/Berlin
time: 2012-03-01 14:31:47.296000000 Z
updated_at: !ruby/object:ActiveSupport::TimeWithZone
utc: 2021-05-20 16:32:01.093000000 Z
zone: *1
time: 2021-05-20 18:32:01.093000000 Z
actors: "-4"
group_name: ''
As you can see the template
contains long html template data. So far so good. This works fine and perfect, and if something changes its easy to diff in pull requests.
But for some reason sometimes the text content gets escaped.
Example:
---
guid: aPsOeyYUbumlfZI2yLs2ti
name: infobase
template: "<tpl for=\".\">\n <a name=\"infobase-{id}\"></a>\n\n <div class=\"papersheet\"
style=\"padding:0\">\n <tpl if=\"folder.folder_type\">\n <tpl if=\"folder.folder_type.tools.length
> 0\"><div class=\"buttoncontainer border-bottom\"></div></tpl>\n </tpl>\n
\ \n {[this.infobase.messages(values)]}\n\n <div class=\"infobase\" style=\"padding:
5mm 15mm\">\n\n <div class=\"header greytext border-bottom\">\n <div
data-qtip=\"{folder.path}/{folder.name}\">{folder.name:htmlEncode}</div>\n <div>\n
\ <tpl if=\"owner.mail\"><a href=\"mailto:{owner.mail}?subject={[escape(values.topic)]}\">{owner.name:htmlEncode}</a></tpl>\n
\ <tpl if=\"!owner.mail\">{owner.name}</tpl>\n </div>\n <div>{[Ext.util.Format.date(values.changed_at,
InformerContext.format.dateshort)]}</div>\n </div>\n\n <div class=\"largetext
boldtext\" style=\"line-height: 22px;margin:10px 0;\">{topic}</div>\n\n <tpl
if=\"attachment.file||attachment.source\">\n <div class=\"linkcontainer border-bottom\">\n
\ <tpl if=\"attachment.file\">{attachment.file:this.attachment.link}<br
/></tpl>\n <tpl if=\"attachment.source\">{attachment.source:this.attachment.link}</tpl>\n
\ </div>\n </tpl>\n\n <div class=\"content\"><div>{description:nl2br}</div></div>\n\n
\ <tpl if=\"locked\"><div class=\"lockedcontent mediumtext\">{[t(\"infobase.messages.record_locked\")]}</div></tpl>\n
\ <tpl if=\"content.length > 0 && locked == false\">\n <div class=\"content
clear\">{content}</div>\n <tpl if=\"attachment.file.media.type == 'video'\"><center>{attachment.file:this.attachment.html5video}</center></tpl>\n
\ <tpl if=\"attachment.file.media.type == 'flv'\"><center>{attachment.file:this.attachment.flashvideo}</center></tpl>\n
\ </tpl>\n\n <tpl if=\"members.length > 0 || member_of.length > 0\">\n
\ <div class=\"membercontainer border-top\">\n <tpl if=\"members.length
> 0 \">\n <div class=\"memberscontainer\">\n <span class=\"boldtext\">{[t(\"infobase.effective_documents\")]}</span>\n
\ <ul>\n <tpl for=\"members\">\n <li>\n
\ <a href=\"{url.reader}\" target=\"_reader\" data-qtip=\"{[t(\"infobase.folder\")]}:
{folder.name}\">{topic:htmlEncode}</a>\n <tpl if=\"attachment.file\">{attachment.file:this.attachment.iconlink}</tpl>\n
\ </li>\n </tpl>\n </ul>\n </div>\n
\ </tpl>\n <tpl if=\"member_of.length > 0 \">\n <div
class=\"memberofcontainer\">\n <span class=\"boldtext\">{[t(\"infobase.effective_document_of\")]}</span>\n
\ <ul>\n <tpl for=\"member_of\">\n <li>\n
\ <a href=\"{url.reader}\" target=\"_reader\" data-qtip=\"{[t(\"infobase.folder\")]}:
{folder.name}\">{topic:htmlEncode}</a>\n <tpl if=\"attachment.file\">{attachment.file:this.attachment.iconlink}</tpl>\n
\ </li>\n </tpl>\n </ul>\n </div>\n
\ </tpl>\n <br style=\"clear:both\"/>\n </div>\n </tpl>\n\n
\ <!--// Alle Zusatzfelder ausgeben //-->\n <table class=\"profile-table\"
cellpadding=0 cellspacing=0>\n <tpl for=\"profiles.keys\">\n <tr>\n
\ <th>\n {[ this.infobase.label(parent[0].profiles[values]) ]}:\n
\ </th>\n <td>\n {[ this.infobase.value(parent[0].profiles[values])
]}\n </td>\n </tr>\n </tpl>\n </table>\n\n </div>\n
\ </div>\n</tpl>"
config: "{}"
deactivated: false
created_at: !ruby/object:ActiveSupport::TimeWithZone
utc: 2011-10-11 10:26:08.906000000 Z
zone: &1 !ruby/object:ActiveSupport::TimeZone
name: Europe/Berlin
time: 2011-10-11 12:26:08.906000000 Z
updated_at: !ruby/object:ActiveSupport::TimeWithZone
utc: 2021-04-30 09:12:12.726000000 Z
zone: *1
time: 2021-04-30 11:12:12.726000000 Z
actors: "-4"
group_name: infobase
It has so far I can see nothing todo with then length or any special chars, in fact I did not find out what the reason is. I do want to always store template data in like the first example.
So how and when .to_yaml
decide to escape the data or not and how can I do prevent this behavior?
Upvotes: 0
Views: 144
Reputation: 6899
The issue is with lines that include only spaces.
These will format how you want:
puts({ text: "Text A\nText B" }.to_yaml)
---
:text: |-
Text A
Text B
puts({ text: "Text A\n\nText B" }.to_yaml)
---
:text: |-
Text A
Text B
But this won't:
puts({ text: "Text A\n \nText B" }.to_yaml)
---
:text: "Text A\n \nText B"
This behavior may be so that it doesn't end up producing YAML that isn't formatted correctly. You may want to strip blank lines out before saving the data or before serializing.
Upvotes: 1