1
votes

I've improved several image widgets by extending 'apostrophe-images-widgets' directly. That may not be the best practice, but I used this since the beginning I've started to code with apostrophe-cms and It worked good. My slide widget for example only uses this lines in index.js:

module.exports = {
  extend: 'apostrophe-images-widgets',
  piecesModuleName: 'apostrophe-images',
  label: 'Slider Widget'
};

Now my widget.html is the following:

<div class="slider fullscreen">
  <ul class="slides">

    {% block items %}

      {% for entry in data.widget._pieces %}
        {% set image = entry.item or entry %}
        {% set relationship = entry.relationship %}

        <li>
          <img
            data-image src="{{ apos.attachments.url(image.attachment, { size: data.options.size or 'full', crop: relationship }) }}"
            srcset="{{ apos.images.srcset(image.attachment) }}"
            sizes="{{ data.options.sizesAttr or '100vw' }}"
            alt="{{ image.title }}"
          >

          <div class="caption {{ image.align }}">

            {% block title %}
              <h3 class="accent-color truncate hide-on-small-only"
                {% if image.titleColor %}
                  style="color:{{ image.titleColor }}"
                {% endif %}
              >
                {{ image.title }}
              </h3>
            {% endblock %}

            {% block description %}
              {% if image.description %}
                <p class="flow-text"
                  {% if image.descriptionColor %}
                    style="color:{{ image.descriptionColor }}"
                  {% endif %}
                >
                  {{ image.description | nlbr }}
                </p>
              {% endif %}
            {% endblock %}

          </div>

          {% block credit %}
            {% if image.credit %}
              <div class="credit">
                {% if image.creditUrl %}
                    <a href="{{ image.creditUrl }}" target="_blank">
                {% endif %}
                      <span>{{ image.credit }}</span>
                {% if image.creditUrl %}
                    </a>
                {% endif %}
            </div>
            {% endif %}
          {% endblock %}

        </li>

      {% endfor %}
    {% endblock %}

  </ul>
</div>

Now my question is how can I add options like sizesAttr and focalPoint: true etc to my Slider widget?

As i told above if its possible I don't want to add additional fields like you explained here:

  addFields: [
    {
      name: '_image',
      type: 'joinByOne',
      withType: 'apostrophe-image',
      label: 'Image',
      required: true,
      idField: 'imageId',
      filters: {
        projection: {
          attachment: true,
          description: true,
          title: true
        }
      }
    }
  ]

It would be necessary to rewrite the widget to extend: apostrope-pieces-widgets instead apostrope-images-widgets and so on. So my idea is to add the desired options directly with beforeConstruct unfortunately that hasen't worked so I'm stuck there:

module.exports = {
  extend: 'apostrophe-images-widgets',
  piecesModuleName: 'apostrophe-images',
  label: 'Slider Widget',
  beforeConstruct: function(self, options) {
    if (options.focalPoint === undefined) {
      options.focalPoint = true;
    }
  }
};

Do you have maybe an hint, how I can do this? Maybe there is some example in you code how you added options with beforeConstruct or even in html with nujucks with some variables like that {%- set data.widget.options ... -%} ?

1

1 Answers

1
votes

You are dealing with two different types of options there, but they are both declared in the same place. focalPoint is a built-in option, enabling the focal point UI (which then lets you get focal point information back later) and sizesAttr is an example from the documentation of a custom option that you might create for your specific needs.

In both cases, they are passed into the area's widget options in the page or piece show page template. So this might be in default.html for a "default" page or show.html for a piece type's show page like so:

{{ apos.area(data.page, 'content', {
  widgets: {
    'image': {
      sizesAttr: '(min-width: 1024px) 50vw, 100vw',
      focalPoint: true
    }
  }
}) }}

(data.page would be specific to a page, but would be data.piece for a piece's show page)

Then in the widget templates (your widget.html) they're referenced as properties on data.options as you can see with sizesAttr in your example. You could similarly add any random option like foo: 'bar' in the area's widget config, then reference it as data.options.foo in the widget template.

focalPoint is not as useful to reference directly. As a built-in option, it enables special functionality for the focal point, which is then referenced in templates using methods like apos.attachments.hasFocalPoint(). The documentation has more on that.