【问题标题】:How to make Netlify CMS' list widget returns number如何使 Netlify CMS 的列表小部件返回数字
【发布时间】:2018-06-04 22:56:11
【问题描述】:

我想为我的 Jekyll 网站使用 Netlify CMS,我有这样的布局:

{% for skills in page.skills %}
    <div class="guide-skill">
        <div class="guide-skill-fill">
            {% for i in (1..15) %}
            <div class="{% if skills.levels contains i %}fill{% endif %} skill-check"><p>{{ i }}</p></div>
            {% endfor %}
        </div>
    </div>
{% endfor %}

以及我在使用此布局的文本编辑器中编写的页面的前端:

skills:
  - levels:
      - 1

代码运行良好,fill 类已正确添加。

但是当我使用带有列表小部件的 Netlify CMS 时,它会向 levels 列表返回字符串而不是数字,如下所示:

skills:
  - levels:
      - '1'

所以代码不起作用,如何让它返回数字?

我尝试过的

  • 引用i,但它给了我一个错误
  • 使用valueType : "int",无效

我的配置

- label: "Hero Skills"
  name: "skills"
  widget: "list"
  required: false
  fields:
      - {label: "Skill Number", name: "number", widget: "number"}
      - {label: "Levels", name: "levels", widget: "list"}

【问题讨论】:

  • 当你查看你的frontmatter时,你会得到数字周围的引号吗?
  • 在 CloudCannon 中可以非常优雅地解决这个问题:docs.cloudcannon.com/editing/front-matter/#number
  • @talves 是的....
  • 您实际上并没有使用数字小部件 - 您在列表小部件中输入值,它只输出字符串。如果您将数字字段嵌套在列表字段中,您将获得一个对象列表,这仍然不是您想要的。开始怀疑 Netlify CMS 是否需要允许通过位于小部件和输出之间的转换器修改单个值。或者使 valueType 配置选项成为由多个小部件实现的约定。

标签: jekyll netlify netlify-cms


【解决方案1】:

没有一个内置小部件可以输出数字列表(不是字符串),但是当内置小部件不起作用时,您始终可以使用自定义小部件。自定义小部件是 React 组件,我们为那些不使用模块系统的人发布全局挂钩(createClassh)。文档中的更多内容:https://www.netlifycms.org/docs/custom-widgets/#registerwidget

对于您的特定情况,您可以修改文档示例中的类别小部件,使其仅处理数字并同时输出它们。在 Netlify CMS 的 index.html 文件的正文标记末尾添加:

<script>
  var NumberListControl = createClass({
    handleChange: function(e) {
      var value = e.target.value.replace(/[^0-9, ]/, '');
      this.props.onChange(value.split(',').map(function(val) {
        var trimmed = val.trim();
        return trimmed ? parseInt(trimmed, 10) : trimmed;
      }));
    },

    render: function() {
      var value = this.props.value;
      return h('input', {
        type: 'text',
        value: value ? value.join(', ') : '',
        onChange: this.handleChange,
        className: this.props.classNameWrapper,
      });
    }
  });

  var NumberListPreview = createClass({
    render: function() {
      return h('ul', {},
        this.props.value.map(function(val, index) {
          return h('li', {key: index}, val);
        })
      );
    }
  });

  CMS.registerWidget('number_list', NumberListControl, NumberListPreview);
</script>

【讨论】:

    【解决方案2】:

    使用 NetlifyCMS 'Number' widget 允许将数字写入字符串或数值。

    如果你的首要问题是获取一个字符串值,你应该使用valueType

    - label: "Hero Skills"
      name: "skills"
      widget: "list"
      required: false
      fields:
        - {label: "Skill Number", name: "number", widget: "number", valueType: "int", default: 1}
        - {label: "Levels", name: "levels", widget: "list"}
    

    【讨论】:

    • 我已经在问题中写了,它不起作用,我知道为什么
    • 这是一个有趣的用例。我可以看到 Shawn 指的是什么,但是当您要求 valueType 时,CMS 似乎应该更优雅地处理这个问题或错误
    • 同意 - 开始怀疑valueType 是否应该是大多数小部件中实现的约定,尽管接受的值会有所不同。
    【解决方案3】:

    你不能像这样使用数学过滤器来强制这个字符串转换为数字吗?

    {{ yourstring | divided_by:1 }}
    

    来源:https://help.shopify.com/themes/liquid/filters/math-filters#divided_by

    更新

    由于之前的方案不易实现,我选择了另一个角度来解决这个问题。以下代码不假设级别是数字:

    {% for skills in page.skills %}
        <div class="guide-skill">
            <div class="guide-skill-fill">
                {% assign all_levels = "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15" | split: ',' %}
                {% for level in all_levels %}
                <div class="{% if skills.levels contains level %}fill{% endif %} skill-check"><p>{{ level }}</p></div>
                {% endfor %}
            </div>
        </div>
    {% endfor %}
    

    【讨论】:

    • 我在哪里实现它?似乎无法弄清楚,因为字符串在前面
    • 好点...我已经用替代解决方案更新了我的答案。
    • 我想你没抓住重点,html 的位置很好,问题是 CMS 返回的前面的值是字符串类型的。
    • 你是对的。我知道。我的解决方案是一种变通方法。
    • 而且,看看其他答案,看来我的替代解决方案毕竟还不错。 :-)
    猜你喜欢
    • 2020-07-06
    • 2020-04-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 2020-07-18
    相关资源
    最近更新 更多