Guidance on converting HTML tables to portable objects in Sanity CMS.
7 replies
Last updated: Mar 12, 2023
M
Hello Everyone,I’m migrating my blog website from Netlify to Sanity CMS. I’m using this package sanity/block-tools to convert the blog body content HTML to portable objects. Everything is working fine except for the HTML Tables. Can you please guide me on how can I achieve it?
M
user M
M
Hello Everyone, Any response here?
K
Hey
Schema example:
user S
have you tried the the blockContentTypeoption to define a custom block type for tables?
Schema example:
// schema.js
import { ... } from '@sanity/schema-builder'
export default createSchema({
// ...
types: [
// ...
{
name: 'table',
type: 'object',
title: 'Table',
fields: [
{
name: 'rows',
type: 'array',
of: [
{
type: 'array',
of: [
{
type: 'string',
},
],
},
],
},
],
preview: {
select: {
rows: 'rows',
},
prepare(rows) {
return {
title: `Table (${rows.length} rows)`,
subtitle: rows.map((r) => r.join(' | ')).join('\n'),
}
},
},
},
],
})M
user B
No I have not tried. Here’s my current Schema:export default {
name: "bodyPortableText",
type: "array",
title: "Post body",
of: [
{
type: "block",
title: "Block",
// Styles let you set what your user can mark up blocks with. These
// corrensponds with HTML tags, but you can set any title or value
// you want and decide how you want to deal with it where you want to
// use your content.
styles: [
{ title: "Normal", value: "normal" },
{ title: "H1", value: "h1" },
{ title: "H2", value: "h2" },
{ title: "H3", value: "h3" },
{ title: "H4", value: "h4" },
{ title: "Quote", value: "blockquote" },
],
lists: [
{ title: "Bullet", value: "bullet" },
{ title: "Number", value: "number" },
],
// Marks let you mark up inline text in the block editor.
marks: {
// Decorators usually describe a single property – e.g. a typographic
// preference or highlighting by editors.
decorators: [
{ title: "Strong", value: "strong" },
{ title: "Emphasis", value: "em" },
],
// Annotations can be any object structure – e.g. a link or a footnote.
annotations: [
{
name: "link",
type: "object",
title: "URL",
fields: [
{
title: "URL",
name: "href",
type: "url",
validation: (Rule) =>
Rule.uri({
allowRelative: true,
scheme: ['http', 'https', 'mailto', 'tel', '/'],
}),
},
],
},
{
name: 'internalLink',
type: 'object',
title: 'Internal link',
fields: [
{
name: 'reference',
type: 'reference',
title: 'Reference',
to: [
{ type: 'post' },
// other types you may want to link to
]
}
]
}
],
},
of: [{ type: "authorReference" }]
},
// You can add additional types here. Note that you can't use
// primitive types such as 'string' and 'number' in the same array
// as a block type.
{
type: "mainImage",
options: { hotspot: true },
},
],
};M
Here’s the html table that I would like to convert into the portable objects and fit it in the above schema.
<table style="width:100%;border-collapse:collapse;table-layout:fixed;height:747px;border:1px solid #99acc2"><tbody><tr style="height:37px"><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2"><strong>Lender</strong>
</td><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2"><strong>Average Rate
Spread</strong></td><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2"><strong>Amount Originated in
2021</strong></td></tr><tr style="height:37px"><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2">PennyMac Servicing</td><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2">-0.39</td><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2"><span>
</span><span>$17,514,705,000</span></td></tr><tr style="height:37px"><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2"><br><span>Home Point
Financial</span></td><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2">-0.36</td><td style="width:33.3333%;height:37px;padding:4px;border:1px solid #99acc2">$7,247,505,000</td></tr></tbody></table>K
try this revised Schema….notice the use of blockContent
export default {
name: “bodyPortableText”,
type: “array”,
title: “Post body”,
of: [
{
type: “block”,
title: “Block”,
// Styles let you set what your user can mark up blocks with. These
// corrensponds with HTML tags, but you can set any title or value
// you want and decide how you want to deal with it where you want to
// use your content.
styles: [
{ title: “Normal”, value: “normal” },
{ title: “H1", value: “h1” },
{ title: “H2", value: “h2” },
{ title: “H3", value: “h3” },
{ title: “H4", value: “h4” },
{ title: “Quote”, value: “blockquote” },
],
lists: [
{ title: “Bullet”, value: “bullet” },
{ title: “Number”, value: “number” },
],
// Marks let you mark up inline text in the block editor.
marks: {
// Decorators usually describe a single property – e.g. a typographic
// preference or highlighting by editors.
decorators: [
{ title: “Strong”, value: “strong” },
{ title: “Emphasis”, value: “em” },
],
// Annotations can be any object structure – e.g. a link or a footnote.
annotations: [
{
name: “link”,
type: “object”,
title: “URL”,
fields: [
{
title: “URL”,
name: “href”,
type: “url”,
validation: (Rule) =>
Rule.uri({
allowRelative: true,
scheme: [‘http’, ‘https’, ‘mailto’, ‘tel’, ‘/’],
}),
},
],
},
{
name: ‘internalLink’,
type: ‘object’,
title: ‘Internal link’,
fields: [
{
name: ‘reference’,
type: ‘reference’,
title: ‘Reference’,
to: [
{ type: ‘post’ },
// other types you may want to link to
]
}
]
}
],
},
of: [
{
type: “authorReference”,
},
{
type: “table”,
title: “Table”,
blockContentType: “table”,
},
],
},
// You can add additional types here. Note that you can’t use
// primitive types such as ‘string’ and ‘number’ in the same array
// as a block type.
{
type: “mainImage”,
options: { hotspot: true },
},
],
// Define the custom block type for tables
types: [
{
name: “table”,
type: “object”,
fields: [
{
name: “content”,
type: “array”,
of: [{ type: “row” }],
},
],
},
{
name: “row”,
type: “object”,
fields: [
{
name: “cells”,
type: “array”,
of: [{ type: “cell” }],
},
],
},
{
name: ”
export default {
name: “bodyPortableText”,
type: “array”,
title: “Post body”,
of: [
{
type: “block”,
title: “Block”,
// Styles let you set what your user can mark up blocks with. These
// corrensponds with HTML tags, but you can set any title or value
// you want and decide how you want to deal with it where you want to
// use your content.
styles: [
{ title: “Normal”, value: “normal” },
{ title: “H1", value: “h1” },
{ title: “H2", value: “h2” },
{ title: “H3", value: “h3” },
{ title: “H4", value: “h4” },
{ title: “Quote”, value: “blockquote” },
],
lists: [
{ title: “Bullet”, value: “bullet” },
{ title: “Number”, value: “number” },
],
// Marks let you mark up inline text in the block editor.
marks: {
// Decorators usually describe a single property – e.g. a typographic
// preference or highlighting by editors.
decorators: [
{ title: “Strong”, value: “strong” },
{ title: “Emphasis”, value: “em” },
],
// Annotations can be any object structure – e.g. a link or a footnote.
annotations: [
{
name: “link”,
type: “object”,
title: “URL”,
fields: [
{
title: “URL”,
name: “href”,
type: “url”,
validation: (Rule) =>
Rule.uri({
allowRelative: true,
scheme: [‘http’, ‘https’, ‘mailto’, ‘tel’, ‘/’],
}),
},
],
},
{
name: ‘internalLink’,
type: ‘object’,
title: ‘Internal link’,
fields: [
{
name: ‘reference’,
type: ‘reference’,
title: ‘Reference’,
to: [
{ type: ‘post’ },
// other types you may want to link to
]
}
]
}
],
},
of: [
{
type: “authorReference”,
},
{
type: “table”,
title: “Table”,
blockContentType: “table”,
},
],
},
// You can add additional types here. Note that you can’t use
// primitive types such as ‘string’ and ‘number’ in the same array
// as a block type.
{
type: “mainImage”,
options: { hotspot: true },
},
],
// Define the custom block type for tables
types: [
{
name: “table”,
type: “object”,
fields: [
{
name: “content”,
type: “array”,
of: [{ type: “row” }],
},
],
},
{
name: “row”,
type: “object”,
fields: [
{
name: “cells”,
type: “array”,
of: [{ type: “cell” }],
},
],
},
{
name: ”
M
Thanks
user B
you made my day.Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.