How do I check if collection contains an object with a specific key in handlebars - bigcommerce

Assuming custom_fields contains this data, and I want to find out if it has an item/object with the name = "hide_options". I want to pass this to a component.
WARNING
Using occurrences in this way is a hack. If the name isn't unique enough, you may get false-positives
[
{"id":"12","name":"hide_options","value":"true"},
{"id":"13","name":"state","value":"colorado"},
{"id":"14","name":"city","value":"colorado, springs"}
]
The closest I've come up with is this:
templates\components\products\product-view.html
{{> components/products/conditionallyVisibile
hideOptions=(occurrences (join (pluck product.custom_fields "name") ",") "hide_options")
}}
components/products/conditionallyVisibile.html
<div>
hideOptions {{ hideOptions }}
</div>
Am I missing an easier Array or Collection helper that would make this easier? Most of the Array/Collection helpers are block helpers.
EDIT:
I was missing a significantly easier way to do this via the Filter Array Helper
{{#filter product.custom_fields "hide_options" property="name"}}
{{> components/products/conditionallyVisibile hideOptions=true }}
{{else}}
{{> components/products/conditionallyVisibile hideOptions=false }}
{{/filter}}
EDIT 2:
the scalar-form of
(occurrences (join (pluck product.custom_fields "name") ",") "hide_options")
is almost-equivalent to the block-form
{{#inArray (pluck product.custom_fields 'name') 'hide_options' }}

Related

Hugo Pass Shortcode Variables From Pages Into sitemap.xml

Currently Hugo's built-in sitemap generator only creates two field attributes for images -- image:loc and image:license. Unfortunately this does not tell Google Bots much about the images context for SEO. The fields, image:title & image:caption at minimum is needed with the other two for best practices; Otherwise it's basically dead XML code.
I am working on a site that is image-content driven and since a short code is given in each page labeled as "Featured-Image" and contains the needed variables where I would like to extract/pass into the sitemap.
Here is an example of the shortcode within a page.md:
{{<
featured-image
name ="THE_IMAGE_NAME.jpg"
featuredTitle ="THE_IMAGE_TITLE"
location ="THE_IMAGE_LOCATION"
alt ="THE_IMAGE_ALT/CAPTION"
>}}
Within the sitemap.xml is what I would like to do:
{{ $license := .Site.Params.schema.license }}
{{ range .Data.Pages }}
...
{{ range $i := .Resources.ByType "image" }}
// Below is the additional data I am wanting to get from the pages'
// shortcode named "featured-image" -- But How Do I Get It?.
{{ $caption := .Get "alt" }}
{{ $location := .Get "location"}}
{{ $title := .Get "featuredTitle"}}
<image:image>
<image:loc>{{ $i.Permalink }}</image:loc>
<image:license>{{ $license }}</image:license>
// Below are the additional attributes needed:
<image:geo_location>{{ $location }}</image:geo_location>
<image:title>{{ $title }}</image:title>
<image:caption>{{ $caption }}</image:caption>
</image:image>
...

filter an object key:val in vue

I have an object with key:val I want to filter the object by value like "ג6"
how i do that? I dont have alias name for search
this is the object
specialityTest={
"4969": "ג6",
"4973": "ג19",
"5163": "ה",
"5165": "ה1",
"5200": "ה2",
"5486": "גן1"
}
I want to do
this.nurseListSpeciality2 = this.specialityTest.filter((el) => {
return el.value == "fffff";
});
I get an error:
this.specialityTest.filter is not a function
how can I filter this object?
You can use Object.keys for filtering your keys where the values match.
this.nurseListSpeciality2 = Object.keys(this.specialityTest).filter((val) => this.specialityTest[val] === "ג6");
Finally, when rendering you can loop over the array of keys that will be returned and the render values associated with those keys
<ul>
<li v-for="val in nurseListSpeciality2" :key="val">
{{ specialityTest[val] }}
</li>
</ul>

how to insert a new empty line on selected index number in an array using \n. while we loop through it using v-for and create a list

want to insert a new empty line before a selected array element while we loop through it using v-for to create a list..trying to do this using \n isn't working
<!-- this is the template part -->
<ul>
<li v-for = "ninja in ninjas" > {{ninja}}</li>
</ul>
/* this is the script part notice index no 2 in the array*/
data() {
return {
ninjas: [
'mati kahe kumhaar sey, tu kya ronday mohey',
' Ik din aisa aayega mai rondungi tohe',
'\n aaye hain toh jaayengay Raja, Rank, fkeer',
' Ik sinhaasan chodi chale, Ik baandhay zanjeer'
]
};
},
This is pretty easy to do using the <pre> tag which forces it to preserve white space, new lines, etc. This is often used for preserving formatting in code examples.
<div id="app">
<ul>
<li v-for = "ninja in ninjas" ><pre>{{ninja}}</pre></li>
</ul>
</div>
working example: https://jsfiddle.net/skribe/10yL6va8/8/
You will probably want to use css to style the text surrounded by <pre> since most browsers automatically format it differently.

how can get index & count in vuejs

I have code like this (JSFiddle)
<li v-for="(itemObjKey, catalog) in catalogs">this index : {{itemObjKey}}</li>
Output:
this index: 0
this index: 1
My question is:
How can I get value index first begin: 1 for example I want
output like this: this index: 1 this index: 2
How can I get count from index, i.e. output like this: this index: 1 this index: 2 this count: 2 field
you can just add 1
<li v-for="(catalog, itemObjKey) in catalogs">this index : {{itemObjKey + 1}}</li>
to get the length of an array/objects
{{ catalogs.length }}
In case, your data is in the following structure, you get string as an index
items = {
am:"Amharic",
ar:"Arabic",
az:"Azerbaijani",
ba:"Bashkir",
be:"Belarusian"
}
In this case, you can use extra variable to get the index in number:
<ul>
<li v-for="(item, key, index) in items">
{{ item }} - {{ key }} - {{ index }}
</li>
</ul>
Source: https://alligator.io/vuejs/iterating-v-for/
Alternatively, you can just use,
<li v-for="catalog, key in catalogs">this is index {{++key}}</li>
This is working just fine.
The optional SECOND argument is the index, starting at 0. So to output the index and total length of an array called 'some_list':
<div>Total Length: {{some_list.length}}</div>
<div v-for="(each, i) in some_list">
{{i + 1}} : {{each}}
</div>
If instead of a list, you were looping through an object, then the second argument is key of the key/value pair. So for the object 'my_object':
var an_id = new Vue({
el: '#an_id',
data: {
my_object: {
one: 'valueA',
two: 'valueB'
}
}
})
The following would print out the key : value pairs. (you can name 'each' and 'i' whatever you want)
<div id="an_id">
<span v-for="(each, i) in my_object">
{{i}} : {{each}}<br/>
</span>
</div>
For more info on Vue list rendering: https://v2.vuejs.org/v2/guide/list.html
Using Vue 1.x, use the special variable $index like so:
<li v-for="catalog in catalogs">this index : {{$index + 1}}</li>
alternatively, you can specify an alias as a first argument for v-for directive like so:
<li v-for="(itemObjKey, catalog) in catalogs">
this index : {{itemObjKey + 1}}
</li>
See : Vue 1.x guide
Using Vue 2.x, v-for provides a second optional argument referencing the index of the current item, you can add 1 to it in your mustache template as seen before:
<li v-for="(catalog, itemObjKey) in catalogs">
this index : {{itemObjKey + 1}}
</li>
See: Vue 2.x guide
Eliminating the parentheses in the v-for syntax also works fine hence:
<li v-for="catalog, itemObjKey in catalogs">
this index : {{itemObjKey + 1}}
</li>
Hope that helps.
Why its printing 0,1,2...?
Because those are indexes of the items in array, and index always starts from 0 to array.length-1.
To print the item count instead of index, use index+1. Like this:
<li v-for="(catalog, index) in catalogs">this index : {{index + 1}}</li>
And to show the total count use array.length, Like this:
<p>Total Count: {{ catalogs.length }}</p>
As per DOC:
v-for also supports an optional second argument (not first) for
the index of the current item.
this might be a dirty code but i think it can suffice
<div v-for="(counter in counters">
{{ counter }}) {{ userlist[counter-1].name }}
</div>
on your script add this one
data(){return {userlist: [],user_id: '',counters: 0,edit: false,}},

Laravel Display a record details while grouped by year or month

I just moved to the laravel framework and am starting to migrate some legacy sites and I have hit a problem with SQL or blade - dunno which.
I have to display a load of rows 'sports classes' which are grouped by year and then month. each needs to show attendance etc.
I am unsure which way to proceed.
I am able to display all rows and sort by date - easy squeezy
I am able to groupBy year AND month - fiddly but sorted it.
These are all displayed in an accordian.
Click the month - the individual rows drop down - you get the idea
I can get a number of rows per month/year
What I am unable to figure out is how to actually display the rows.
The groupBy is this:
$LinkClasses = DB::table('classes_lists')
->select('id, class, teacher, size')
->select(DB::raw('YEAR(date) AS year, MONTH(date) AS month, MONTHNAME(date) AS month_name, COUNT(*) post_count'))
->groupBy('year')
->groupBy('month')
->orderBy('year', 'desc')
->orderBy('month', 'desc')
->orderBy('id', 'desc')
If the code you provided is within your controller, then you can append ->get() after your last ->orderBy(). This will return a Collection. You can then do whatever you want with the Collection (http://laravel.com/api/master/Illuminate/Support/Collection.html), including conversion to an array using ->toArray(), but I think it would be best to utilize the Eloquent ORM if possible.
Anyway, once you have it in the format you want, just pass it to the view like so:
return view('your.view', compact('LinkClasses'));
Then, inside the your.view blade template, you can access this by using the following:
#foreach ($LinkClasses as $currentRow)
<tr>
<td>{{ $currentRow['id'] }}</td>
<td>{{ $currentRow['class'] }}</td>
<td> ... </td>
</tr>
#endforeach
Best guess I can offer without seeing the blade template to get a better idea of what you're doing. Hope that helps!
UPDATE BASED ON OP FEEDBACK:
Since you are only receiving a single record, it seems as though the issue lies in your query. I suggest you simplify your query to fetch all records and then do your sorting within an array. Something like this in your controller:
$allClasses = DB::table('classes_lists')->all();
foreach ($allClasses as $currentClass) {
$yearMonth = date('Y-m', $currentClass['date']);
$classesByYearMonth[$yearMonth][] = $currentClass;
}
ksort($classesByYearMonth);
/* now you have an array of all classes sorted by year-month like this:
// $classesByYearMonth[2014-01] = array(
// [0] => array(1, 'class name', 'teacher name', 23),
// [1] => array(2, 'another class', 'different teacher', 25),
// ...
// );
//
// $classesByYearMonth[2014-02] = ...
*/
return view('your.view', compact('classesByYearMonth'));
Then, inside your blade template:
#foreach ($classesByYearMonth as $yearMonth => $classListArray)
Found {{ sizeof($classListArray) }} classes for {{ $yearMonth }}
#foreach ($classListArray as $currentClass)
<div>
<div>ID: {{ $currentClass['id'] }}</div>
<div>Class: {{ $currentClass['class'] }}</div>
<div>Teacher: {{ $currentClass['teacher'] }}</div>
<div>Size: {{ $currentClass['size'] }}</div>
</div>
#endforeach
#endforeach
I will leave it to you to fix the formatting to make your accordion work. But hopefully that will get you on the right path.
DNoe - thank you so much.
Your reply put me on exactly the right track.
I had to mod some bits due to laravel ambiguities and add the strtotime but the logic was all there.
foreach ($allClasses as $currentClass) {
$ym = $currentClass['date'];
$yearMonth = date("Y-m",strtotime($ym));
$classesByYearMonth[$yearMonth][] = $currentClass;
}
krsort($classesByYearMonth);
return View::make('classes.index', compact('classesByYearMonth'));
The css is simple from here.
I owe you some beers. And thanks for helping me take my head from my butt!
Send me a pm and i would be very very happy to forward beer donation :o
Great work and thank you again. :)
Also, part of the problem was that the results were throwing an stdObject rather than an array.
Being able to compare your code with my own has enabled me to create a dbquery with multiple joins from which meaningfull data is selected and then converted to an array.
$classes = DB::table('table2')
->join('table1', 'table2.id', '=', 'table1.id2' )
->join('table3', 'table1.id3', '=', 'table3.id' )
->orderBy('classes_lists.date','DESC')
->get(array('table1.id', 'teacher', 'date', 'size', 'students', 'fname', 'classname', 'table1.notes'));
$cfr = count($classes);
foreach($classes as $object)
{
$arrays[] = (array) $object;
}
foreach ($arrays as $currentClass){
$ym = $currentClass['date'];
$yearMonth = date("Y-m",strtotime($ym));
$clazByYearMonth[$yearMonth][] = $currentClass;
}
krsort($clazByYearMonth);
This was the output into blade:
Not formatted :
#foreach ($clazByYearMonth as $yearMonth => $classListArray)
Found {{ sizeof($classListArray) }} classes for {{ $yearMonth }}
#foreach ($classListArray as $currentClass)
<div>
date: {{ $currentClass['date'] }} | class: {{ $currentClass['classname'] }} | Size: {{ $currentClass['size'] }} Teacher: {{ $currentClass['fname'] }} |
</div>
#endforeach
#endforeach