我如何在自定义 HTML 周围使用自定义 CSS 文件放置 CKEditor 内联输出?

How can I couch the CKEditor inline output in custom surrounding HTML with custom CSS files?

假设我在 CKEditor 中有以下来源:

<p>This is my <b>description</b> content.</p>

保存时。我知道它将进入我网站上的内容块,如下所示:

<html>
  <head>
    <link href="//styles.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div id="content">
      <div id="heading">{{ heading }}</div>
      <div id="description">{{ description }}</div>
    </div>
  </body>
</html>

假设文件 styles.css 具有以下规则:

#description p {
  text-indent: 15px;
}
#description b {
  font-size: larger;
}

我想做的是能够在我打字时看到网站上的内容。现在我确信这可以通过手动将这些样式插入编辑器来逐步完成,但这是行不通的,因为我们的站点样式要复杂得多,并且会根据我们所在的站点而有所不同。我需要做的是用下面的标签包围编辑器中的内容,这样 CSS 文件中的内容就会自然地在编辑器显示中生效,让我们的编辑对他们将看到的内容有一个现实的期望一旦他们的故事出现在网站上。

简而言之,我需要这样的东西:

cke.before_code = '<html><head><link href="//styles.css" rel="stylesheet" type="text/css"></head><body><div id="content"><div id="description">';
cke.after_code = '</div></div></body></html>';

然后我希望看到的输出是这样的:

before_code + "whatever the editor is typing presently" + after_code

希望一切都清楚。如果有人对如何实现这一点有任何建议,将不胜感激。

我无法找到一种方法来按照我上面要求的方式集成 html/样式。考虑到在这个问题上一直保持沉默,我怀疑我在这里提出的要求可能无法实现。然而,我确实找到了一种使用预览按钮实现下一个最佳效果的方法。根据我们的编辑正在编辑的项目,单击预览按钮现在将显示该特定项目的即时预览,其样式就像它在我们的网站上一样。这里有一个 step-by-step 供有兴趣的人使用。

首先,假设我们有以下内容要开始:

CKEDITOR.replace('editor', config);

其次,我们要将以下内容添加到 config 并将其放在上面一行之前,以便将事件注册到编辑器:

Object.assign(config, {
  on: {
    contentPreview: function(e) {
      let match = e.data.dataValue.match(/<body[^>]*>((?:.|\s)*)<\/body>/),
        before = '' +
          '<html>' +
            '<head>' +
            '</head>' +
            '<body>',
        content = match[1],
        after = '' +
            '</body>' +
          '</html>;
      e.data.dataValue = before + content + after;
    }
  }
});

content 现在将包含用户在编辑器中输入的任何内容。通过将 beforecontentafter 添加在一起,我们最终得到将在预览中显示的网页。只是现在,页面在我们的控制之下,我们可以根据编辑器正在查看的页面,页面上的其他字段等进行调整,我们可以在我们网站的实时样式中添加 links .

假设我现在想在我的网站样式中添加 Bootstrap 和 link。假设我想用一种类型的容器包围内容,如果编辑正在处理博客,如果他正在处理新闻报道,则用另一种容器。在这种情况下,我可能会这样做:

Object.assign(config, {
  on: {
    contentPreview: function(e) {
      let match = e.data.dataValue.match(/<body[^>]*>((?:.|\s)*)<\/body>/),
        before = '' +
          '<html>' +
            '<head>' +
              '<link href="//stackpath.bootstrapcdn.com/bootstrap/4.5.6/css/bootstrap.min.css" rel="stylesheet" type="text/css">' +
              '<link href="//mylivesite.com/styles.css" rel="stylesheet" type="text/css">' +
              '<script src="//mylivesite.com/scripts.js"></' + 'script>' +
            '</head>' +
            '<body>',
        content = match[1],
        after = '' +
            '</body>' +
          '</html>;
      if (location.pathname.indexOf('blog') > -1)
        content = '' +
          '<div class="row blog">' +
            '<div class="col-sm-8">' + content + '</div>' +
            '<div class="col-sm-4">Blog Right Column Content</div>' +
          '</div>';
      else
        content = '' +
          '<div class="row news">' +
            '<div class="col-sm-8">' + content + '</div>' +
            '<div class="col-sm-4">News Right Column Content</div>' +
          '</div>';
      e.data.dataValue = before + content + after;
    }
  }
});

现在,当预览打开时,它将具有实时网站的所有样式以及 bootstrap 列,因此编辑器可以使用浏览器查看所有内容在不同维度下的外观。

从某种意义上说,这比在您键入时仅在编辑器中看到样式要好(尽管那样仍然很好),因为它允许编辑器了解内容在上下文中的外观在加载样式和执行脚本后它出现的页面。如果内容根据编辑器选择的选项而有所不同,您可以在呈现预览之前根据这些值动态构建预览页面。

这是我最终得到的解决方案,我的人对此非常满意,所以我想我会分享。