How to include var in partials calls - assemble

Let's say I have a website where for each main section I have a specific sidebar.
Currently I have a single sidebar file, where im using categories to filter the correct content to show like this:
{{#inArray page.categories "Components"}}
<section class="sg-index">
<ul>
<li {{#is title "DetailContent"}} class="active"{{/is}}>
DetailContent
</li>
However my goal is to have these sidebar files located at each section folder, along with the section files.
How can I include the {{dirname}} variable in the partials call {{> sidebar}}?

This should be possible with a conditional block helper, like {{with}} and the include helper,
B you could also create a custom helper, something like this:
var path = require('path');
var _ = require('lodash');
var matter = require('gray-matter');
module.exports.register = function (Handlebars, options, params) {
var assemble = params.assemble;
var grunt = params.grunt;
var opts = options || {};
Handlebars.registerHelper('sidenav', function(page, context) {
if(page.published !== false && page.sidenav) {
if(!Array.isArray(assemble.partials)) {
assemble.partials = [assemble.partials];
}
var filepath = _.first(_.filter(assemble.partials, function(fp) {
return path.basename(fp, path.extname(fp)) === page.sidenav;
}));
// Process context, using YAML front-matter,
// grunt config and Assemble options.data
var pageObj = matter(filepath) || {};
var metadata = pageObj.context || {};
context = _.extend(this, opts.data[page.sidenav], metadata, context);
var partial = Handlebars.partials[page.sidenav];
var template = Handlebars.compile(partial);
var output = template(context);
// Prepend output with the filepath to the original partial
// for debugging
var sidenav = opts.sidenav || opts.data.sidenav || {};
if(sidenav.origin === true) {
output = '<!-- ' + filepath + ' -->\n' + output;
}
return new Handlebars.SafeString(output);
}
});
};
then use it in your markup like this:
<div class="sidebar" role="complementary">
<ul class="nav sidenav">
{{sidenav this}}
</ul>
</div>

Related

Dropzone - multiple instances get id

I have multiple dropzone forms
<form action="/upload" class="dropzone" id="group1"></form>
<form action="/upload" class="dropzone" id="group2"></form>
<form action="/upload" class="dropzone" id="group3"></form>
How do I get the id of the form the file is dropped into?
To hook into a Dropzone action like a file being added, you'll need to use an event handler. From the docs:
Dropzone triggers events when processing files, to which you can register easily, by calling .on(eventName, callbackFunction) on your instance.
So you'll need to manually instantiate your Dropzones, to get access to the instance.
If you're using jQuery:
// Don't automatically instantiate, we'll do it manually
Dropzone.autoDiscover = false;
// Using the jQuery syntax shown in the docs
$("#group1, #group2, #group3").dropzone({
init: function() {
var formID = this.element.attributes.id;
this.on("addedfile", function(file) {
console.log('Image dropped on form ID', formID);
});
}
});
If you're not using jQuery:
Dropzone.autoDiscover = false;
var dz = [],
forms = document.getElementsByTagName('form');
for (var i = 0; i < forms.length; i++) {
dz[i] = new Dropzone(forms[i], {
init: function() {
var formID = this.element.attributes.id;
this.on("addedfile", function(file) {
console.log('Image dropped on form', formID);
});
}
});
}

How to force cursive display in ckeditor while typing

<!DOCTYPE html>
<html>
<head>
<script src="http://cdn.ckeditor.com/4.6.2/standard/ckeditor.js"></script>
</head>
<body>
<textarea name="editorUrdu"></textarea>
<script>
CKEDITOR.plugins.addExternal( 'easykeymap', '/ckeditor/plugins/easykeymap', 'plugin.js' );
CKEDITOR.replace( 'editorUrdu',{
extraPlugins: 'easykeymap',
contentsLangDirection: 'rtl'
});
</script>
</body>
</html>
/**
* This work is mine, and yours. You can modify it as you wish.
* #Author: Roni Saha<roni.cse#gmail.com>
*
* This source file is subject to the MIT license that is bundled
* with this source code in the file LICENSE.
*/
CKEDITOR.plugins.add('easykeymap',
{
requires : ['wysiwygarea'],
init: function (editor) {
//var keyMaps = CKEDITOR.tools.extend({}, editor.config.easykeymaps || {}, true);
//Not using keymap specification from config variables, but using internally defined ones from param below
function isRegisteredKeystroke(code) {
if(typeof editor.keystrokeHandler.keystrokes[code] != 'undefined') {
console.warn("the keystroke : " + code + " is being attached to another event")
return true;
}
return false;
}
var sm1 = []; var en1 = [];
sm1[192]="؏"; en1[192]="~";
sm1[49]="۱"; en1[49]="1";
sm1[50]="۲"; en1[50]="2";
sm1[51]="۳"; en1[51]="3";
sm1[52]="۴"; en1[52]="4";
sm1[53]="۵"; en1[53]="5";
sm1[54]="۶"; en1[54]="6";
sm1[55]="۷"; en1[55]="7";
sm1[56]="۸"; en1[56]="8";
sm1[57]="۹"; en1[57]="9";
sm1[48]="۰"; en1[48]="0";
sm1[189]="-"; en1[189]="-";
sm1[187]="="; en1[187]="=";
//sm1[8]=""; en1[8]="";//BACKSPACE
var sm2 = []; var en2 = [];
sm2[9]=""; en2[9]="";//TAB
sm2[81]="ق"; en2[81]="Q";
sm2[87]="و"; en2[87]="W";
sm2[69]="ع"; en2[69]="E";
sm2[82]="ر"; en2[82]="R";
sm2[84]="ت"; en2[84]="T";
sm2[89]="ے"; en2[89]="Y";
sm2[85]="ء"; en2[85]="U";
sm2[73]="ی"; en2[73]="I";
sm2[79]="ہ"; en2[79]="O";
sm2[80]="پ"; en2[80]="P";
sm2[219]="'"; en2[219]="{";
sm2[221]="ﷲ"; en2[221]="}";
sm2[220]="÷"; en2[220]="\\";
var sm3 = []; var en3 = [];
//sm3[20]=""; en3[20]="";//CAPSLOCK
sm3[65]="ا"; en3[65]="A";
sm3[83]="س"; en3[83]="S";
sm3[68]="د"; en3[68]="D";
sm3[70]="ف"; en3[70]="F";
sm3[71]="گ"; en3[71]="G";
sm3[72]="ح"; en3[72]="H";
sm3[74]="ج"; en3[74]="J";
sm3[74]="ک"; en3[75]="K";
sm3[76]="ل"; en3[76]="L";
sm3[186]="؛"; en3[186]=":";
sm3[222]=","; en3[222]="\"";
sm3[13]=""; en3[13]="";//ENTER
var sm4 = []; var en4 = [];
//sm4[16]=""; en4[16]="";//SHIFT
sm4[90]="ز"; en4[90]="Z";
sm4[88]="ش"; en4[88]="X";
sm4[67]="چ"; en4[67]="C";
sm4[86]="ط"; en4[86]="V";
sm4[66]="ب"; en4[66]="B";
sm4[78]="ن"; en4[78]="N";
sm4[77]="م"; en4[77]="M";
sm4[188]="،"; en4[188]="<";
sm4[190]="۔"; en4[190]=">";
sm4[191]="/"; en4[191]="?";
sm4[16]=""; en4[16]="";//SHIFT
var keyBoard = {};
keyBoard.Row1 = { "sm" : sm1, "en" : en1 };
keyBoard.Row2 = { "sm" : sm2, "en" : en2 };
keyBoard.Row3 = { "sm" : sm3, "en" : en3 };
keyBoard.Row4 = { "sm" : sm4, "en" : en4 };
function getMappedCharacter(code) {
console.info(code);
if (typeof keyBoard.Row1.sm[code] != 'undefined')
return keyBoard.Row1.sm[code]
else if (typeof keyBoard.Row2.sm[code] != 'undefined')
return keyBoard.Row2.sm[code]
else if (typeof keyBoard.Row3.sm[code] != 'undefined')
return keyBoard.Row3.sm[code]
else if (typeof keyBoard.Row4.sm[code] != 'undefined')
return keyBoard.Row4.sm[code]
else
return false;
}
editor.on( 'key', function( event ) {
var t = event.target;
var mappedCode = getMappedCharacter(event.data.keyCode);
if (mappedCode !== false && !isRegisteredKeystroke(event.data.keyCode)) {
event.cancel();
if(typeof mappedCode == 'function') {
return mappedCode.call(editor, editor);
}
editor.insertText(mappedCode);
}
} );
}
});
I'm using ckeditor for allowing my users to input Urdu text. Like Arabic, Urdu is cursive, and uses distinct ligatures when joined.
I'm using the
editor.on( 'key', function( event ))
event to intercept the
event.data.keyCode
and replace it using
editor.insertText()
function.
So, e.g. if the user types L and A, I replace it with the Urdu
ا (U+0627)
and
ل (U+0644).
Now, after being typed, they both appear as distinct characters, separate from each other. I can press space, or enter, and they both remain as they are. But I would like them to be replaced with their proper equivalent ligature ﻻ which is FEFB in this unicode chart
I see that ckeditor automatically correct this if I switch to Source view. There, inside the <p> block, it shows the separate, disjointed letter's already replace with proper cursive ligature. And it keeps it that way when I switch back from Source view. But whatever is causing this to happen, how can I trigger that to happen while typing?
Attaching images also.
After typing
After going to source view
After returning from source view
When ever you type L and A , editor.insertText() is just append it as two separate stings, instead of combining into one.
<p>"ل"
"ا"
<br>
</p>
that why its not producing desired output.
Added these two line
var $pTag = editor.getSelection().getRanges()[0].startContainer.$; // accessing the p tag
$pTag.innerText = $pTag.innerText+mappedCode; // modifing the inner text
replacing
editor.insertText(mappedCode); // in editor.on( 'key', function( event )
will output as "لا"
above fix has some issues to deal with like linebeak(new line)
Updated
replace the below snippet
var $pTag = editor.getSelection().getRanges()[0].startContainer.$;
var innerText =$pTag.innerText; // accessing the p tag data
$pTag.innerText = ""; // removing the existing data
editor.insertHtml(innerText+mappedCode); // concat with new string
with
editor.insertText(mappedCode); // in editor.on( 'key', function( event )
Example: codepen

Dynamically generate React component names

I'm having trouble finding a solution to this. How can I convert the code below into something more dynamic and succinct?
OneComponent = require ('./OneComponent')
TwoComponent = require ('./TwoComponent')
ThreeComponent = require ('./ThreeComponent')
Example = React.createClass
render: ->
filter = #props.filterState
if filter is 'something'
tableCmpt =
<div>
<OneComponent
tasks={#props.tasks}
/>
</div>
if filter is 'somethingElse'
tableCmpt =
<div>
<TwoComponent
tasks={#props.tasks}
/>
</div>
##... etc
return tableCmpt
I've done something like this.
var Components = {
'something': require('./Component'),
'somethingElese': require('./Component2')
};
Example = React.createClass({
render: function() {
var component = Components[this.props.filter];
return <div><component tasks={this.props.tasks}/></div>;
}
});
I couldn't get Crob's answer to work (though I appreciate the hash table idea), but it led me to find a solution - I just skipped the jsx step and used the compiled js:
React.createElement(component, {tasks: this.props.tasks} )
So all in all:
var Components = {
'something': require('./Component'),
'somethingElese': require('./Component2')
};
Example = React.createClass({
render: function() {
var component = Components[this.props.filter];
React.createElement(component, {tasks: this.props.tasks} )
}
});

CQ5/AEM6/Sightly - Return custom type from Java Use-Api

Using JavaScript Use-Api I am able to create a custom object and return it to a html file. This feature allows me to create a list of custom objects, which can be used to create a menu or other complex list-like component.
Let's assume that I have following content structure:
/content
/project
/homepage
/contentpage1
/contentpage1.1
/contentpage1.2
/contentpage1.3 (hidden)
/contentpage2
/contentpage1.1 (hidden)
/contentpage1.2 (hidden)
/contentpage1.3 (hidden)
/contentpage3
/contentpage4
Menu should contains only first-level contentpages. Each menu item should have dropdown list with second-level contentpages, if they exist and are not hidden. I can do it in JavaScript with the following code:
"use strict";
use(function() {
function getMenuItems() {
var currentPageDepth = currentPage.getDepth();
var menuObjects = [];
if(currentPageDepth >= 3) {
var homePage = currentPage.getAbsoluteParent(2);
var list = homePage.listChildren();
while(list.hasNext()) {
var tempPage = list.next()
var customPageObject = createMenuItemObject(tempPage);
menuObjects.push(customPageObject);
}
}
return menuObjects;
}
function createMenuItemObject(page) {
// ...
// looking for any other properties of page or its children
// ...
return {page: page,
visibleChildrenExists: visibleChildrenExists(page)};
}
function visibleChildrenExists(page) {
var list = page.listChildren();
var visibleChildrenExists = false;
while(list.hasNext()) {
var subPage = list.next();
if(!subPage.isHideInNav()) {
visibleChildrenExists = true;
break;
}
}
return visibleChildrenExists;
}
return {
menuObjectsList: getMenuItems(),
};
}
HTML:
<headerComponent data-sly-use.headerComponentJS="headerComponent.js" data-sly-unwrap />
<menuItems data-sly-list.menuItem="${headerComponentJS.menuObjectsList}" data-sly-unwrap >
<li class='${menuItem.visibleChildrenExists ? "" : "direct"}' data-sly-test="${!menuItem.page.hideInNav}">
${menuItem.page.title}
<ul data-sly-test="${menuItem.visibleChildrenExists}" data-sly-list.submenuItem="${menuItem.page.listChildren}">
<li data-sly-test="${!submenuItem.hideInNav}">
${submenuItem.title}
</li>
</ul>
</li>
</menuItems>
Why do I want to use Java Use-Api? It's easier to operate on interfaces like Resource or Node. It looks like it does not work pretty well in JavaScript, but I need to have possibility to return custom objects with multiple properties.
The question is: is it even possible to do something similar using Java Use-Api? What do I have to return? I can't return a map, because it won't be possible to access its elements since it's not possible to pass a parameter to Java Use-Api method... Any suggestion?
It is possible to return maps using the java-use api see an example below:
Method in the Java class
//Return a map
public Map<String, String> getTestMap() {
//TODO some coding
Map<String,String> testMap = new HasMap<String,String>();
testMap.put("IDA", "test value");
testMap.put("IDB", "test value 2");
return testMap;
}
HTML code to access each element of the map:
<div data-sly-use.param="JavaClass">
<div data-sly-test.map="${param.testMap}">
<div class="pos">
<span class="classA">${map['IDA']}</span><br>
<span class="classB">${map['IDB']}</span>
</div>
</div>
</div>

Splitter control in SAPUI5

I am trying to implement SAPUI5 splitter button/control that accepts one Label and one button like Linked in. Like linked in when you add your skills, text display along with delete button. If you want to delete the text then simple click on delete button, it will delete (this is what happens in linked in).
I am also want to implement same thing using SAP splitter control but i am facing some layout issue. I have tried a lot to fix this issue but no luck.
Here is my code
In code there three splitters in total. Main splitter called oSplitterH that saves 0.....n sub-sublitters in its addFirstPaneContent.
The problem is it always display split button in vertical alignment rather than horizontal like linked in. I also changed the layout into Horizontal but still displaying in vertical alignment.
Any suggestion?
var splitterLabel = new Label({
text : 'Splitter ',
width: '80px'
});
var oSplitterH = new sap.ui.commons.Splitter("splitterH");
oSplitterH.setSplitterOrientation(sap.ui.commons.Orientation.Horizontal);
oSplitterH.setSplitterPosition("200%%");
oSplitterH.setMinSizeFirstPane("20%");
oSplitterH.setMinSizeSecondPane("30%");
oSplitterH.setWidth("200%");
//adding Labels to both panes
var oSplitter2 = new sap.ui.commons.Splitter("splitterH12");
oSplitter2.setSplitterOrientation(sap.ui.commons.Orientation.Vertical);
oSplitter2.setSplitterPosition("10%");
oSplitter2.setMinSizeFirstPane("10%");
oSplitter2.setMinSizeSecondPane("10%");
oSplitter2.setWidth("20%");
var oLabel2 = new sap.ui.commons.Label({text: "Part1"});
oSplitter2.addFirstPaneContent(oLabel2);
var oLabel2 = new sap.ui.commons.Label({text: "Part2"});
oSplitter2.addFirstPaneContent(oLabel2);
var oSplitter3 = new sap.ui.commons.Splitter("splitterH13");
oSplitter3.setSplitterOrientation(sap.ui.commons.Orientation.Vertical);
oSplitter3.setSplitterPosition("10%");
oSplitter3.setMinSizeFirstPane("10%");
oSplitter3.setMinSizeSecondPane("10%");
oSplitter3.setWidth("20%");
var oLabe123 = new sap.ui.commons.Label({text: "Part3"});
oSplitter3.addFirstPaneContent(oLabe123);
var oLabe1234 = new sap.ui.commons.Label({text: "Part4"});
oSplitter3.addFirstPaneContent(oLabe1234);
oSplitterH.addFirstPaneContent(oSplitter2);
oSplitterH.addFirstPaneContent(oSplitter3);
createProfileMatrix.createRow(splitterLabel, oSplitterH, null, null);
The following code may help you.
index.html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link rel="stylesheet" href="main.css"/>
<script src="resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.commons"
data-sap-ui-theme="sap_goldreflection">
</script>
<!-- add sap.ui.table,sap.ui.ux3 and/or other libraries to 'data-sap-ui-libs' if required -->
<script>
sap.ui.localResources("sapui5samples");
var view = sap.ui.view({id:"idlinkedIn-label1", viewName:"sapui5samples.linkedIn-label", type:sap.ui.core.mvc.ViewType.JS});
view.placeAt("content");
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
<div id="list"></div>
</body>
</html>
main.css
.tech-area{
border:1px solid gray;
border-radius: 5px;
width:500px;
height:300px;
left:0;
top:50;
position:relative;
overflow:scroll;
}
SAPUI5 view file (didn't used controller file)
var oLayout;
sap.ui.jsview("sapui5samples.linkedIn-label", {
getControllerName : function() {
return "sapui5samples.linkedIn-label";
},
createContent : function(oController) {
// create a simple SearchField with suggestion list (list expander
// visible)
var oSearch = new sap.ui.commons.SearchField("suggestSearch1", {
enableListSuggest : true,
startSuggestion : 1,
search : function(oEvent) {
var techName = oEvent.getParameter("query");
addTechnology(techName);
},
suggest : doSuggest
});
// Button for adding the technology if it is not listed in the available
// technologies
var oButton = new sap.ui.commons.Button({
text : "Add",
tooltip : "Add Technology",
press : function() {
var tech = sap.ui.getCore().byId("suggestSearch1").getValue();
addTechnology(tech);
}
});
// create a simple horizontal layout
var oLayout = new sap.ui.commons.layout.HorizontalLayout({
content : [ oSearch, oButton ]
});
// attach it to some element in the page
oLayout.placeAt("content");
oLayout = new sap.ui.commons.layout.HorizontalLayout("target");
oLayout.addStyleClass("tech-area");
// attach it to some element in the page
oLayout.placeAt("list");
}
});
// Help function to handle the suggest events of the search field
var doSuggest = function(oEvent) {
var sVal = oEvent.getParameter("value");
var aSuggestions = filterTechnologies(sVal); // Find the technologies
var oSearchControl = sap.ui.getCore().byId(oEvent.getParameter("id"));
oSearchControl.suggest(sVal, aSuggestions); // Set the found suggestions on
// the search control
};
var technologies = [ "Java", ".Net", "PHP", "SAPUI5", "JQuery", "HTML5", "" ];
technologies.sort();
jQuery.sap.require("jquery.sap.strings"); // Load the plugin to use
// 'jQuery.sap.startsWithIgnoreCase'
// Help function to filter the technologies according to the given prefix
var filterTechnologies = function(sPrefix) {
var aResult = [];
for (var i = 0; i < technologies.length; i++) {
if (!sPrefix || sPrefix.length == 0
|| jQuery.sap.startsWithIgnoreCase(technologies[i], sPrefix)) {
aResult.push(technologies[i]);
}
}
return aResult;
};
var count = 0;
var arr = [];
// function for add the item to horizontal layout
var addTechnology = function(techName) {
var elementIndex = arr.indexOf(techName);
// conditional statement for adding the tech to the list
if (elementIndex === -1) {
count++;
// create a horizontal Splitter
var oSplitterV = new sap.ui.commons.Splitter({
width : "120px",
height : "30px",
showScrollBars : false,
splitterBarVisible : false
});
oSplitterV.setSplitterOrientation(sap.ui.commons.Orientation.vertical);
oSplitterV.setSplitterPosition("60%");
oSplitterV.setMinSizeFirstPane("60%");
oSplitterV.setMinSizeSecondPane("40%");
// label with dynamic Id
var oLabel1 = new sap.ui.commons.Label("tCount" + count, {
text : techName,
tooltip : techName
});
oSplitterV.addFirstPaneContent(oLabel1);
var oLabel2 = new sap.ui.commons.Button({
icon : "img/delete.png",
press : function() {
removeElement(techName);
oSplitterV.destroy();
}
});
oSplitterV.addSecondPaneContent(oLabel2);
sap.ui.getCore().byId("target").addContent(oSplitterV);
// Adding the tech to the parent array
arr.push(techName);
// Emptying the search box
sap.ui.getCore().byId("suggestSearch1").setValue("");
} else {
sap.ui.commons.MessageBox.alert(techName
+ " is already added to the list");
}
}
// function for removing removed element from parent array
var removeElement = function(addedTech) {
// Find and remove item from an array
var i = arr.indexOf(addedTech);
if (i != -1) {
arr.splice(i, 1);
}
}
Please make a note that I concentrated more on functionality rather than look and feel
Thanks,
prodeveloper