Default value for images in apostrophe cms? - node.js

I have a custom widget:
module.exports = {
extend: 'apostrophe-widgets',
label: 'Banner',
addFields: [
{
name: 'bannerImg',
type: 'attachment',
label: 'Picture',
def: 'http://via.placeholder.com/350x150'
}
]
};
And widget view:
<img class="logo" src="{{ apos.attachments.url(data.widget.bannerImg) }}" />
If I load image It's Ok I see it. But I don't have the default value. Also can I choose file from gallery without upload?

I spent a half of the day and found the solution:
as answered in: How to define widgets with default values in Apostrophe CMS
{% if apos.areas.isEmpty(data.widget, 'bannerImg') %}
<h1>Default Value</h1>
{% endif %}
{{ apos.singleton(data.widget, 'bannerImg', 'apostrophe-images', { limit: 1 }) }}
And also if we want to get href of this images:
{{ apos.attachments.url(apos.images.first(data.widget.bannerImg)) }}
Also in index.js I changed on:
{
name: 'bannerImg',
type: 'singleton',
label: 'Banner',
widgetType: 'apostrophe-images',
options: {
limit: 1
}
},

Related

How do I format [future, non-current] dates in Eleventy + Nunjucks?

I'm building a site with a CMS (Netlify) for a local band, and they have future gig dates they will put on the site. So far the dates show up as very long non-formatted strings that include the time and time zone. I'm trying to figure out how to format the dates to be simpler (day, date, time for example).
I've tried plugins like nunjucks-date but I'm a little confused about how to use a plugin (and filters) in this case.
My repo: https://github.com/mollycarroll/serapis-eleventy-2
Example gig entry:
---
layout: gig
venue: Cedar Lake Cellars
date: 2022-05-28
time: 6pm
city: Wright City, MO
---
Gig template:
<h2>{{ venue }}</h2>
<h4>{{ city }} {{ date }} {{ time }}</h4>
config.yml for the CMS:
- name: 'gigs'
label: 'Shows'
folder: 'src/gigs'
create: true
slug: '{{month}}-{{day}}-{{venue}}'
fields:
- { label: 'Layout', name: 'layout', widget: 'hidden', default: '_includes/gig.njk' }
- { label: 'Date', name: 'date', widget: 'date', default: '' }
- { label: 'Time', name: 'time', widget: 'string', default: '' }
- { label: 'Venue', name: 'venue', widget: 'string', default: '' }
- { label: 'City', name: 'city', widget: 'string', default: '' }
Thanks for any help.
First, you should create a filter, let's say src/filters/date.js with the following content:
const { DateTime } = require("luxon");
// Add a friendly date filter to nunjucks.
// Defaults to format of LLLL d, y unless an
// alternate is passed as a parameter.
// {{ date | friendlyDate('OPTIONAL FORMAT STRING') }}
// List of supported tokens: https://moment.github.io/luxon/docs/manual/formatting.html#table-of-tokens
module.exports = (dateObj, format = 'LLLL d, y') => {
return DateTime.fromISO(dateObj, { zone: "Europe/Amsterdam", locale: "en" }).toFormat(format);
};
Make sure you check Luxon documentation for details. Then add the filter in .eleventy.js:
module.exports = function(eleventyConfig) {
...
eleventyConfig.addFilter("date", require("./src/filters/date.js"));
...
};
Now you can use it in Nunjacks with a default value {{ date }}, in this example 'LLLL d, y', or any value you need at a certain position on your website {{ date | date('dd. LLLL yyyy.') }}. This can be very useful if you need at some point just month and year or just day and month.
You can even create multiple language filters, like dateEn.js and dateDe.js, and format each to its own language if you have a multilingual site.
Hope this helps.
EDIT: In order for this filter to work the dateObj should be in ISO 8601 format.

Adding Dropdowns in a vue.js router-link

I have created a vue.js router and inserting the links found in an array using the structure found hereafter. This displays the links horizontally. However, I would like to insert dropdowns, instead of simple links. Can this be done using this or similar structure somehow?
<nav style="text-align: right">
<router-link class="spacing" v-for="routes in links"
v-bind:key="routes.id"
:to="`${routes.page}`">{{routes.text}}</router-link>
</nav>
links: [
{
id: 0,
text: 'Buy',
page: '/Buy'
},
{
id: 1,
text: 'Sale',
page: '/Sale'
},
{
id: 2,
text: 'Transactions',
page: '/Transactions'
},
{
id: 3,
text: 'Help',
page: '/Help'
}
]
Yeah, there are a few ways you could do that, though you'll have to loop over something different than the <router-link>, since that component renders an <a> tag.
I would first adjust your HTML to allow for the drop-down interaction you want, whether it's hover- or click-based, then change your data structure and loop to support it.
I might do something like this:
<nav style="text-align: right">
<div
class="nav-item"
v-for="link in links" // Move loop to container of shown link and it's dropdown markup
>
<router-link
:key="link.id"
:to="`${link.page}`"
>
{{ link.text }}
</router-link>
<div class="nav-item-drawer">
<router-link
v-for="subLink in link.subLinks"
:key="subLink.id"
:to="`${subLink.page}`"
>
{{ subLink.text }}
</router-link>
</div>
</div>
</nav>
with the following data structure:
links: [
{
id: 0,
text: 'Buy',
page: '/Buy',
subLinks: [
{
id: 0,
text: 'Buy Sublink 1',
page: '/Buy-more'
},
{
id: 1,
text: 'Buy Sublink 2',
page: '/Buy-less'
},
]
},
{
id: 1,
text: 'Sale',
page: '/Sale'
},
//...
]

Spaceless tag inside script block

I'm trying to inline this so the rendered page isn't 100,000 lines long.
It seems the spaceless tag does nothing here.
Input:
{% for log in logs -%}
{% spaceless %}
{
id: {{ log.id }},
description: '{{ log.description }}'
},
{% endspaceless %}
{% endfor -%}
Expected Output:
{id:17186,description:'Test Log'},
{id:17187,description:'Test Log 2'},
Output:
{
id: 17186,
description: 'Test Log'
},
{
id: 17187,
description: 'Test Log 2'
},
Like the documentation says, you can "use the spaceless tag to remove whitespace between HTML tags, not whitespace within HTML tags or whitespace in plain text."
You can instead control whitespace e.g. like this:
{% for log in logs -%}
{
{{- 'id' }}: {{ log.id }},
{{- 'description' }}: '{{ log.description }}'
{{- '},' }}
{%- endfor %}
The above produces this:
{id: 17186,description: 'Test Log'},{id: 17187,description: 'Test Log 2'},
The downside is that the Twig code is much uglier.
Here's an alternative using string interpolation:
{% for log in logs -%}
{
{{- 'id' }}: {{ log.id }},
{{- 'description' }}: {{ "'#{log.description}'" -}}
},
{%- endfor %}
{id: 17186,description: 'Test Log'},{id: 17187,description: 'Test Log 2'},
The Twig code looks now better, but notice that single quotes got converted to '. You may or may not want to do something about that.
You could also do like the documentation suggests and use a third-party library like Tidy.

Showing category thumbnails in opencart 3 menu

I'm looking for a way to show the category thumbnail in the menu. Is this possible?
Specifically for OpenCart 3.
OpenCart 3.0.2.0, Default theme
Open this file:
catalog\controller\common\menu.php
Find:
$this->load->model('catalog/product');
Add after it:
$this->load->model('tool/image');
Find:
$data['categories'][] = array(
Replace with:
if($category['image']){
$image = $this->model_tool_image->resize($category['image'], 30, 30);
} else {
$image = false;
}
$data['categories'][] = array(
'image' => $image,
Then open this file:
catalog\view\theme\default\template\common\menu.twig
Find:
{{ category.name }}
There are three occurrence, add before first and last one:
<img src="{{ category.image }}" alt="{{ category.name }}"/>{% endif %}
Here is the result:
for submenu use:
$children_data[] = array(
'image' => $child['image'] ? $this->model_tool_image->resize($child['image'], 20, 20) : false,
or
'image' => $child['image'] ? $this->model_tool_image->resize($child['image'], 20, 20) : $this->model_tool_image->resize('your-default-image.jpg', 20, 20),
in template
{% for child in children %}
<li>{% if child.image %}<img src="{{ child.image }}" alt="{{ child.name }}" />{% endif %}{{ child.name }}</li>
{% endfor %}
If missed something, follow here

How to add a style to a {{ form_label(form.name) }}

I'm using Symfony 3.0, in this moment I have this code:
{{ form_label(form.name, 'Name of the card', { 'attr': {'style': 'color:white'}}) }}
Thank you :) !
You need to use label_attr for labels, attr is for the widget function.
{{ form_label(form.name, 'Name of the card', { 'label_attr': {'style': 'color:white'}}) }}
According to the documentation rendering form row involves three functions
{{ form_label(form.name) }}
{{ form_errors(form.name) }}
{{ form_widget(form.name) }}
You can replace form_label(form.name) with your layout
<div class="form_label">Name of the card</div>
<div class ="form_errors">{{ form_errors(form.name) }}</div>
{{ form_widget(form.name) }}

Resources