I am having trouble creating a custom image widget in Apostrophe CMS. The current apostrophe-images-widgets
works fine for more images, but I need a special case for the website logo as it needs specific css and a specific location on the website.
I tried following the tutorial here for making a custom widget with a manager, but I have no gotten the results I would like. Here is my logo-image
module
module.exports = {
extend: 'apostrophe-pieces',
name: 'logo-image',
label: 'Website Logo',
addFields: [
{
name: 'companyName',
label: 'Company Name',
type: 'string',
required: true
},
{
name: 'logo',
label: 'Logo',
type: 'singleton',
widgetType: 'apostrophe-images',
options: {
limit: 1,
minSize: [ 200, 200 ]
}
}
],
construct: function(self, options) {
self.beforeSave = function(req, piece, options, callback) {
piece.companyName = 'Freedom Mutts';
return callback();
};
}
};
which I registered in app.js
like so
modules: {
'logo-image': {}
}
Then, I have a logo-image-widgets
module with an index.js
like so
module.exports = {
extend: 'apostrophe-pieces-widgets',
label: 'Website Logo',
filters: {
projection: {
slug: 1,
title: 1,
type: 1,
tags: 1
}
}
};
and a modules/logo-image-widgets/views/widget.html
like so
<a class="navbar-brand" href="/">{{
apos.singleton(
piece,
'logo',
'apostrophe-images',
{
edit: false
}
)
}}</a>
and a base layout like so
{% extends data.outerLayout %}
<div class="apos-refreshable" data-apos-refreshable>
{% block beforeMain %}
<nav class="navbar navbar-default navbar-fixed-top nav-back">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false"
aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{{
apos.area(data.page, 'logo', {
widgets: {
'logo-image': {}
}
})
}}
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="active"><a href="#">Home</a></li>
<li><a href="#about">Our Pets</a></li>
<li><a href="#about">About</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><button class="btn header-btn">Donate <span class="sr-only">(current)</span></a></li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
{% endblock %}
{% block main %}
Main code here...
{% endblock %}
{% block afterMain %}
layout code here...
{% endblock %}
</div>
This leaves me with a couple issues, 1) I cannot add the logo image to the website itself, only through the menu bar and 2) I don't think it is actually what I want. I want a custom <img />
tag rendered with my own css classes.
I wasn't too sure where to ask this question, so any advice would be great. I am having a lot of trouble creating more complex custom widgets.
Any help is appreciated. Thanks!
I'm the lead developer of Apostrophe at P'unk Avenue.
What you've done here shows a solid grasp of how pieces and pieces-widgets work, although our convention would be to always give the module itself a plural name (it manages many things) while the name property remains singular (it's what we call one instance of the thing in the database). That's just a style nitpick though, the code is fine.
The advice you really need: there's a much easier way to get where you're going for a single project. Just copy the
lib/modules/apostrophe-images-widgets/views/widgetBase.html
file of the originalapostrophe-images-widgets
module to the filelib/modules/apostrophe-images-widgets/views/widget.html
at project level and hack it up to your heart's content.(You could just copy
widget.html
and override various template blocks inwidgetBase
, but it sounds like your needs wouldn't be met by those blocks alone.)Since you don't want this behavior change for every single widget, use an
if
statement in your template to vary the output based ondata.options.foo
, wherefoo
is any option you're passing to the widget in your home page template. Look at howdata.options.size
is handled now, for instance.If you need extra JavaScript, copy
lib/modules/apostrophe-images-widgets/public/js/always.js
to project level as well; it's very short, consisting of aplay
method that invokes ourjquery-projector
plugin. Yourplay
method can do anything it wants to instead.Having said that, if your goals are more ambitious, take a look at the
apostrophe-images
andapostrophe-images-widgets
modules themselves. They use theattachment
field type, which you can use too, including using it directly in a widget module if you are not interested in having a browseable repository of images for reuse. So you can bypass the "widgets display stuff drawn from a repository of pieces" pattern entirely.