【问题标题】:Migrating Markdown Tables to Rich Text in Contentful creating inline Entries在 Contentful 创建内联条目中将 Markdown 表迁移到富文本
【发布时间】:2021-09-05 05:36:19
【问题描述】:

我想将用 Markdown 编写的长文章迁移到富文本字段。除了桌子,我什么都能处理。 In the documentation it says:

将内容迁移到一个链接条目中,该条目只有一个带有支持内容的 Markdown 字段,这类似于步骤 8 中执行的操作

但我无法让它工作。在提到的第 8 步中,没有创建新条目,仅链接现有条目。我还没有弄清楚如何动态创建一个类型为表的新条目(它只是一个带有名称内容的 Markdown 类型的字段)并在富文本内容中引用它。 derivedLinkedEntries() 想要将引用放入特定字段,但这是内联的,可以存在多次。

我可以在富文本字段中手动创建一个表并内联对内容的引用,但我想使用迁移脚本创建它,但不知道如何。

这些是我的内容类型:

这就是我在控制台上得到的一张桌子:

{
    type: 'table',
    align: [ null, 'center', 'right' ],
    children: [
        { type: 'tableRow', children: [Array], position: [Position] },
        { type: 'tableRow', children: [Array], position: [Position] }
    ],
    position: Position {
        start: { line: 14, column: 1, offset: 970 },
        end: { line: 25, column: 58, offset: 1660 },
        indent: [
            1, 1
        ]
    }
}

这是我到目前为止的代码(为简洁起见):

const {richTextFromMarkdown} = require('@contentful/rich-text-from-markdown')
        
module.exports = function(migration) {
    
    migration.transformEntries({
        contentType: 'article',
        from: ['content'],
        to: ['contentV2'],
        transformEntryForLocale: async function(fromFields, currentLocale)
        {
            let copy        = fromFields.content[currentLocale]

            const content = await richTextFromMarkdown(copy,
                (node) => {
                    let ret = null
                    let didSomething = true

                    node.deriveLinkedEntries()

                    switch (node.type) {
                        case 'image':
                            // ...
                            break;
                        case 'html':
                            // ...
                            break;
                        default:
                            didSomething = false
                    }

                    if (false === didSomething) {
                        console.log(node)
                    }

                    return ret
                }
            )

            return {
                contentV2: {
                    nodeType: 'document',
                    content: content.content,
                    data: {}
                },
            }
        }
    })
}

【问题讨论】:

    标签: typescript markdown data-migration contentful richtext


    【解决方案1】:

    在经历了更多的头痛和良好的睡眠之后,我找到了解决方案:

    const { richTextFromMarkdown } = require('@contentful/rich-text-from-markdown')
    const { createClient } = require('contentful-management')
            
    module.exports = function(migration) 
    {
        const managementClient = createClient({ accessToken: context.accessToken })
        const space            = await managementClient.getSpace(context.spaceId)
        const environment      = await space.getEnvironment(config.activeEnvironmentId)
    
         /**
         * Creates a simple hash for a string
         * @param string
         */
        function createHash(string)
        {
            let hash = 0,
                i,
                chr
    
            if (string.length === 0) {
                return hash
            }
    
            for (i = 0; i < string.length; i++)
            {
                chr   = string.charCodeAt(i);
                hash  = ((hash << 5) - hash) + chr;
                hash |= 0 // Convert to 32bit integer
            }
    
            return hash
        }
    
        /**
         * Extracts part from MarkDown that is the table, transfers content into an
         * entry that is just a MarkDown field. Entry is created if does not exist
         * @param table
         * @param copy
         */
        async function linkTableEntry(table, copy)
        {
            // extract MarkDown for the table from the entered text
            const pos      = table.position
            const strLen   = pos.end.offset - pos.start.offset
            const tableStr = copy.substr(pos.start.offset, strLen)
            const id       = createHash(tableStr) // avoid creating same table twice
            let   entry
    
            try {
                entry = await environment.getEntry(id)
            } catch (e) { }
    
            // create new since it does not exist yet
            if ('undefined' === typeof entry) {
                entry = await createTableEntry(tableStr, id)
            }
    
            return {
                nodeType: 'embedded-entry-block',
                content: [],
                data: {
                    target: {
                        sys: {
                            type: 'Link',
                            linkType: 'Entry',
                            id: entry.sys.id
                        }
                    }
                }
            }
        }
    
        /**
         * Creates a new Entry element with a string representing the table MarkDown
         * The table header is transformed into a title for the Entry
         * @param tablestring
         * @param id
         */
        async function createTableEntry(tablestring, id)
        {
            // create entry title from table header
            const title = tablestring
                            .match(/^.+|\n/g)[0]     // first line
                            .split('|')
                            .filter(Boolean)         // remove empty elements
                            .join(', ')              // Column-Names joined by comma
                            .replace(/\t/g, '')      // remove tabs
                            .replace(/[ ]+,/g, ', ') // no spaces before comma
                            .replace(/[ ]+/g, ' ')   // no multiple spaces
                            .trim()
    
            let entry = await environment.createEntryWithId('table', id, {
                fields: {
                    title: {
                        'de-DE': title
                    },
                    content: {
                        'de-DE': tablestring
                        }
                    }
            })
    
            return await entry.publish()
        }
    
        migration.transformEntries({
            contentType: 'article',
            from: ['content'],
            to: ['contentV2'],
            transformEntryForLocale: async function(fromFields, currentLocale)
            {
                let copy = fromFields.content[currentLocale]
    
                const content = await richTextFromMarkdown(copy,
                    async (node) => {
                        let ret = null
                        let didSomething = true
    
                        node.deriveLinkedEntries()
    
                        switch (node.type) {
                            case 'image':
                                // ...
                                break;
                            case 'html':
                                // ...
                                break;
                            case 'table':
                                ret = await linkTableEntry(node, copy)
                                break
                            default:
                                didSomething = false
                        }
    
                        if (false === didSomething) {
                            console.log(node)
                        }
    
                        return ret
                    }
                )
    
                return {
                    contentV2: {
                        nodeType: 'document',
                        content: content.content,
                        data: {}
                    },
                }
            }
        })
    }
    

    所以基本上这里发生了什么:

    • 我创建了一个新的内容模型table,它只有一个title 和一个长文本字段content
    • 我们使用richTextFromMarkdown() 给出的位置信息(参见问题示例)从内容中提取表格的 MarkDown 字符串
    • 我们为该字符串生成一个简单的哈希,因此如果我们需要重新运行迁移,我们不会创建同一个表两次
    • 如果表已经存在,我们内联现有的表,如果不存在,我们使用 ContentFul 的 managementClient 动态创建一个新表
    • 使用此条目的sys.id,我们可以将链接条目放入富文本字段中

    我希望这对某人有所帮助,因为我找不到任何关于将表格从 MarkDown 迁移到 Contentful 中的富文本。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-28
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-20
      • 1970-01-01
      相关资源
      最近更新 更多