3

I want to use Netlify CMS for my Jekyll site and I have this layout:

{% 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 %}

and the front matter of page that I write in text editor that uses this layout :

skills:
  - levels:
      - 1

the code works fine, the fill class is added properly.

But when I use Netlify CMS with list widget, it returns string instead of number to the levels list, like this :

skills:
  - levels:
      - '1'

So the code doesn't work, how to make it returns number?

What I've tried

  • Quote the i, but it gave me an error
  • Use valueType : "int", didn't work

My config

- label: "Hero Skills"
  name: "skills"
  widget: "list"
  required: false
  fields:
      - {label: "Skill Number", name: "number", widget: "number"}
      - {label: "Levels", name: "levels", widget: "list"}
  • When you look at your frontmatter, you get the quotes around the numbers? – talves Dec 22 '17 at 14:35
  • In CloudCannon this can be solved very elegant: https://docs.cloudcannon.com/editing/front-matter/#number – Mr. Hugo Dec 22 '17 at 14:41
  • @talves yes.... – Faishal Irawan Dec 22 '17 at 16:16
  • 2
    You're not actually using the number widget - you're entering values in the list widget, which only outputs strings. If you nested the number field within the list field, you'd get a list of objects, which still isn't what you want. Starting to wonder if Netlify CMS needs to allow individual values to be modified by a transformer that sits between the widget and the output. Or else make the `valueType` config option a convention that's implemented by multiple widgets. – Shawn Erquhart Dec 22 '17 at 16:23

3 Answers3

7

None of the built in widgets can output a list of numbers (that aren't strings), but you could always use a custom widget when the built in widgets don't work. Custom widgets are React components, and we publish global hooks (createClass, h) for those not using a module system. More in the docs: https://www.netlifycms.org/docs/custom-widgets/#registerwidget

For your particular case, you can modify the Categories widget from the docs example to only deal with numbers and output them as well. Add this at the end of the body tag in your index.html file for Netlify CMS:

<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>
Shawn Erquhart
  • 1,820
  • 2
  • 17
  • 30
3

Using NetlifyCMS 'Number' widget allows for the numbers to be written as string or number value.

You should use valueType if your front matter is getting a string value:

- 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"}
talves
  • 13,993
  • 5
  • 40
  • 63
  • I've written it in the question, it doesn't work, idk why – Faishal Irawan Dec 22 '17 at 15:03
  • 1
    This is an interesting use case. I can see what Shawn is referring to, but seems like the CMS should handle this a little more elegantly or error when you ask for the `valueType` – talves Dec 22 '17 at 22:46
  • Agreed - starting to wonder if `valueType` should be a convention implemented in most widgets, although accepted values would vary. – Shawn Erquhart Dec 24 '17 at 16:21
0

Can't you just use a Math filter to force this string to convert to a number, like this?

{{ yourstring | divided_by:1 }}

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

UPDATE

As the previous solution is not easy to implement, I chose another angle to tackle the problem. The following code does not assume that the level is a number:

{% 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 %}
Mr. Hugo
  • 11,887
  • 3
  • 42
  • 60