如何从富文本中截断?

How to truncate from rich text?

我想从富文本中截断一段文本,如下所示。我尝试了很多东西,但都没有用。

                    {% for piece in data.pieces %}

                        <div class="col-md-4 col-sm-6">
                            <div class="single-product mb-55 animated fadeInUp" data-animate="fadeInUp" data-delay=".1" style="animation-duration: 0.6s; animation-delay: 0.1s;">
                                <span class="tip">{{ piece.title }}</span>
                                <img src="img/products/product1@2x.jpg" data-rjs="2" alt="" data-rjs-processed="true" width="237" height="193">

                                <h3 class="h5">
                                   {{ apos.area(piece, 'body') }}
                                </h3>

                            </div>
                        </div>

                        <!-- End of Single Product -->
                    {% endfor %}

我需要截断这部分。不知道有没有其他方式显示描述:

{{ apos.area(piece, 'body') }}

有许多不同的方法可以解决这个问题,您没有提供太多的要求,因此需要巧妙地满足您的需求。

Note: Using Nunjuck's truncate filter against rich-text (markup) will include all HTML tags and spaces in code against the truncate limit. The examples below use Nunjuck's truncate. This could lead to broken tags in your markup, should a tag be opened, the limit be reached, and then never closed. I would recommend implementing something like truncate-html as a project-level Nunjucks helper. See Implementing custom Nunjucks helpers in Apostrophe

为您的 rich-text-widgets

提供 area-level 截断设置

在您作品的架构中,定义 body 区域时,向您的 apostrophe-rich-text 选项添加一些标志

    {
      name: 'body',
      label: 'Body',
      type: 'area',
      options: {
        widgets: {
          'apostrophe-rich-text': {
            toolbar:[...], // toolbar settings
            styles:[...], // styles settings
            truncate: 250 // truncates after 250 characters
          }
        }
      }
    }

然后,在项目级别重写 apostrophe-rich-text-widgets 模板,注意这些设置是否会传递给 rich-text 小部件。使用 Nunjucks built-in truncate 过滤器更改小部件中的文本内容。

lib/modules/apostrophe-rich-text-widgets/views/widget.html

<div data-rich-text class="apos-rich-text">
  {% if data.options.truncate %}
    {{ data.widget.content | safe | truncate(data.options.truncate) }}  
  {% else %}
    {{ data.widget.content | safe }}  
  {% endif %}
</div>

优点:这将适用于您在上面提供的设置,而无需更改 body.

的当前数据结构

缺点:这种方法是brute-force。您在区域级别指定此选项,因此此区域内的所有 rich-text-widgets 都将收到选项,并且它们将 all 相应地被截断。如果您使用单例来保存您的描述,同样的方法会更好,因为您可以严格控制截断选项发生的位置。

使用截断选项将您的 rich-text 小部件包装到新的小部件中

此方法涉及创建一个新的小部件,其中包含一个 rich-text 单例和用于控制是否截断文本以及截断多少文本的选项。我要调用小部件 truncate-rich-text

lib/modules/truncate-rich-text-widgets/index.js中(创建此文件和路径)

module.exports = {
  extend: 'apostrophe-widgets',
  label: 'Truncate Rich Text',
  addFields: [
    {
      name: 'content',
      label: 'Content',
      type: 'singleton',
      widgetType: 'apostrophe-rich-text',
      options: {
        toolbar:[],
        styles:[]
      }
    },
    {
      name: 'truncate',
      label: 'Truncate this text?',
      type: 'boolean',
      choices: [
        { label: 'Yes', value: true, showFields: ['truncateCharacters'] },
        { label: 'No', value: false }
      ]
    },
    {
      name: 'truncateCharacters',
      label: 'Character limit',
      type: 'integer'
    }
  ]        
};

然后在 lib/modules/truncate-rich-text-widgets/views/widget.html(创建这个)

<div class="truncate-rich-text">
  {% if data.widget.truncate %}
    {{ data.widget.content.items[0].content | safe | truncate(data.widget.truncateCharacters) }}
  {% else %}
    {{ data.widget.content.items[0].content | safe }}
  {% endif %}
</div>

最后,将这个新模块添加到您的 app.js 配置中。

var path = require('path');
var apos = require('apostrophe')({
  shortName: 'myProject',
  modules: {
    // ... other modules
    'truncate-rich-text-widgets': {},
  }
});

优点:这提供了更多 fine-grained 控制哪些文本小部件被截断并且可以在您的站点中更广泛地使用。

缺点:这将是您站点配置中的一个新小部件,这意味着您必须迁移您的内容才能使用它。这也使编辑器用户体验中的 Apostrophe 编辑文本的 in-context 变得很糟糕。

就像我说的,有多种方法可以实现这一点,并且在不同情况下也有用户体验的微妙之处(也许您只向 logged-out 用户显示截断的文本,而将完整内容留给编辑,因为它如果您的文本在保存时不断消失,将会造成混淆)。希望这会为您开辟一些途径来找到正确的实现。