Yeoman: Is it possible to create multistep prompts? - generator

Is it possible to create promps that dipends on previous answers in yeoman generator-generator?
example:
languages supported?
[ ] en
[ ] it
[ ] es
[ ] de
...
and then ask if 'en' is selected
translation of "this thing" in en: ____
and if 'it' is selected
translation of "this thing" in it: ____
etc?
Thank You!

Yeoman is only JavaScript. So yes, it is totally possible to use the answer to launch a new prompt session from the callback.
Inquirer.js documentation even have an example: https://github.com/SBoudrias/Inquirer.js/blob/master/examples/nested-call.js

I found a little (maybe hacky) solution:
https://gist.github.com/matteo-bombelli/f4c8bc17ec83a12cb0de058016aa1f8f#file-index-js-L51
Instead of nesting it inside the promise (wich has geven me problems with the promises timing), I've put it into another task that will be grouped in the default group which is after the prompting.
But I don't like this solution very much. If the use of "then" and the promise can be done would prefer that one.
Thank You!

Related

Override language settings

I found out this particular file which can defined behavior of brackets, etc, in a specific language:
https://code.visualstudio.com/api/language-extensions/language-configuration-guide
I would like to simply configure the addition of '$' before and after selected text in LaTeX documents, using for example 'alt+$' keybinding.
So far, it's not clear to me how to do that, even with the documentation pages I stumbled upon.
(https://code.visualstudio.com/api/references/contribution-points#contributeslanguages for example).
I would think that you could simply do that in keybindings.json but it appears you can't (or I don't know how).
Any idea?
If I understand correctly try this snippet:
{
"key": "shift+alt+4",
"command": "editor.action.insertSnippet",
"args": {
"snippet": "$${TM_SELECTED_TEXT}$"
},
"editorLangId == latex"
},
For where to put that snippet see https://code.visualstudio.com/docs/editor/userdefinedsnippets#_create-your-own-snippets
It doesn't seem you can use alt+$ directly but shift+alt+4 is the same thing.

How would you embed atomic partials into a template data object

I'm using handlebars and assemble with yeoman and gulp.
I want to have some globalized partials that are able to be nested or injected into another partial by calling it within the context of a data object.
A simple example of that would be having a list of links that I could reference inside content throughout the site. The reason behind this, is the need for consistency. If for example, if I have a link within text on a page that I reference a 15 times throughout an entire website, but then realize I need to add a trade mark or modify the text, I want to update it once, not 15 times.
This is an example of what I want to do. Define global data inside a json file:
links.json
{
"apple": {
"linktext": "apple",
"target": "_blank",
"href": "http://www.apple.com"
},
"blog-article-foo-bar": {
"linktext": "foo bar",
"href": "http://www.foobar.com"
},
"dell": {
"linktext": "dell",
"target": "_parent",
"href": "http://www.dell.com"
}
}
Generate a partial from that content using a simple or complex template:
links.hbs
<a href="{{href}}" {{#if target}}target="{{target}}"{{/target}}>{{linktext}}</a>
And be able to embed that partial into another one by referencing it some how. This didn't work, but I've been reading about custom helpers, but can't figure out how I would intercept the partial and bind it into the other partial.
text.json
{
"text": "If you need a computer, go to {{> link link.apple}}."
}
text.hbs
<p>
{{text}}
</p>
compiled.html
<p>
If you need a computer, go to apple.
</p>
If you have suggestions or examples that might help me understand how to achieve this, I'd really appreciate the support. Thanks in advance.
There is some information about Handlebars helpers in their docs but not that much.
Since you're trying to use handlebars syntax in the value of a property on the context (e.g. text), handlebars won't render the value since it's already rendering the template. You can create your own helper that can render the value like this:
Handlebars.registerHelper('render', function(template, options) {
// first compile the template
const fn = Handlebars.compile(template);
// render the compiled template passing the current context (this) to
// ensure the same context is use
const str = fn(this);
// SafeString is used to allow HTML to be returned without escaping it
return new Handlebars.SafeString(str);
});
Then you would use the helper in your templates like this:
{{render text}}
Thanks for the example #doowb, your code did work but not for what I was trying to do. I really wanted something more complicated but I simplified my question not knowing it would be an issue. The code you provided worked (I think after a slight tweak) for a simple render of a template, but my templates use helpers such as #each and #if which caused the issue. Where the helpers were in my template, I ended up getting async placeholders. For example: <a $ASYNC$1$3...> I later learned this has to do with how partials are rendered. Understanding that lead me to subexpressions and the below solution.
Keeping my example above with some modifications, this is how I was able to merge partials.
First, I simplified the placeholder in text.json to basically a unique ID, instead of trying to render the partial there.
On the hbs template that I'm rendering to, such as a page or whatever, I included the insert helper with 3 arguments. The first two are subexpressions, each return a flattened partials as strings. The key here is that subexpressions process and return a result before finishing the current process with the helper. So two flattened templates are then sent to the helper along with the placeholder to search for.
The helper uses the third argument in a regex pattern. It searches the second argument (flattened parent template) for this pattern. When found, it replaces each instance of the pattern with the first argument (yes its a global fine replace).
So, the flattened child string gets inserted into parent each time placeholder is found.
First argument
(partial "link" link.apple)
Returns
'apple'
Second argument
(partial "text" text.text-example)
Returns
'<p class="text font--variant">If you need a computer, go to {{linkToApple}}.</p>'
Third argument
'linkToApple'
text.json
{
"text-example": {
"elm": "quote",
"classes": [
"text",
"font--variant"
],
"text": "If you need a computer, go to {{linkToApple}}."
}
}
text.hbs
<{{elm}} class="{{#eachIndex classes}}{{#isnt index 0}} {{/isnt}}{{item}}{{/eachIndex}}">{{text}}</{{elm}}>
compile.hbs
{{insert (partial "link" link.apple) (partial "text" text) 'linkToApple' }}
compile.html
<p class="text font--variant">If you need a computer, go to apple.</p>
gulpfile.js
app.helper('insert', function(child, parent, name) {
const merged = parent.replace(new RegExp('\{\{(?:\\s+)?(' + name + ')(?:\\s+)?\}\}', 'g'), child);
const html = new handlebars.SafeString(merged);
return html;
});
Hope this helps someone else. I know this can use improvements, I'll try to update it when I get back to cleaning up my gulp file.

How to insert dynamic blocks of html inside SendGrid email?

I'm using SendGrid web API v3. Trying to generate personalization object which includes many recipients. Each recipient has 1 email with data that related to current recipient (pass with substitutions)
Example:
personalizations: [{
to: [{email: 'example#mail.com'}],
subject: 'Hello, :name!',
substitutions: {':name': 'John', ':info_section_html':'<p>Some useful block1</p><p>Some useful block2</p>'}
},
{
to: [{email: 'example#mail.com'}],
subject: 'Hello, :name!',
substitutions: {':name': 'John', ':info_section_html':'<p>Some useful block1</p><p>Some useful block2</p><p>Some useful block3</p><p>Some useful block4</p><p>Some useful block5</p><p>Some useful block6</p>'}
}
],
from: {email: 'send#example.com'},
content: [{type: 'text/html', value: 'Hello, :name! </br> Here are your very usefull info</br> :info_section_html'}]
When substitution: info_section_html has a lot of such blocks it crossed a limit of 10000 bytes. My blocks have a lot more HTML than in example. Each recipient can have a different number of blocks that's why I can't include them in content attribute.
Also was thinking about sections attribute where I can pass HTML of my info_section_html. But can't pass array of data in substitution.
Can someone please suggest how to overcome this?
I know this comes quite late, but I was facing the same issue and couldn't find the answer so I'd figured that maybe it would be useful to still post it here:
As can be found here: SendGrid API v3
A collection of key/value pairs following the pattern "substitution_tag":"value to substitute". All are assumed to be strings. These substitutions will apply to the text and html content of the body of your email, in addition to the subject and reply-to parameters. The total collective size of your substitutions may not exceed 10,000 bytes per personalization object.
So there's nothing to do about it here.
For this usage Sendgrid has another feature called Sections (check link above as well). They work almost like Substitutions except that they're are link to the whole mail and not per Substitution
They can be used together with Substitutions to achieve behavior like stated above.
As said by mbernier here: Github issue related to the topic
You can use them like this:
"personalizations: [
{
"to: [{"email":"bob#example.com"}],
"substitutions": {
"[%product_info%]": "[%has_product%]",
},
},
{
"to":[{"email":"bob#example.com"}],
"substitutions": {
"[%product_info%]": "[%no_product%]",
},
}],
"content": [
{
"type": "text/plain",
"value": "We just wanted to tell you that we appreciate you being a long time customer! [%product info%]"
}],
"sections": {
"[%has_product%]": "Also, thanks for ordering:<br />[%product_section%].<br /> Are you ready to order again!?",
"[%no_product%]": "You haven't ordered in a while, but we'd love it if you came back and saw our new products!"
}
Most important here is that the sections should be added via a substitution tag.
Hope this helps

Sublime Autocompletion for HTML using Emmet inside .sublime-autocompletion file

I tried to create a auto completion with scope of html file. But it is not working...
Can somebody please, find the problem...
{
"scope": "text.html.php.htm",
"completions":
[
{ "trigger": "tta", "contents": ".tabs>ul>(li>a[href='#tabs-$'])*3^^(#tabs-$>p)*3" },
{ "trigger": "accd", "contents": ".accordion>(h4{section$}+#first$>p)*4" }
]
}
The first problem are the scopes. They must be separated by commas and also the scope for PHP source is source.php, not text.php. You can find complete list of scopes here.
You must also escape the $ characters as \\$ otherwise the completion will produce nothing when invoked. I'm not exactly sure why this happens. Anyone feel free to update this answer if you know the reason behind this.

Filtering the iNotes Calendar in extlib

I need too filter the iNotes calendar control in extlib. When I look in the examples in the extlib application I can see that it is suppose to be connected to a xecalendarJsonLegacyService.
The problem I find with this service is that I can't filter the content based on category or search as with the other view services.
I need to create different calendars/json data based on a search or category in a view.
I have looked at some of the other services but not sure if it is possible to use them instead.
If you have any ideas for how I should create my filter, please respond.
I have attached pictures below showing both the jsonservice and the calendarcontrol.
This is what the json data look like in the xsCalendarJsonLegacyService
{
"#timestamp":"20120311T171603",
"#toplevelentries":"3",
"viewentry":
[
{
"#unid":"37F0330979C04AF2C12579BE004F5629",
"#noteid":"32E1A",
"#position":"1",
"#read":"true",
"#siblings":"3",
"entrydata":
[
{
"#columnnumber":"0",
"#name":"$134",
"datetime":
{
"0":"20120314T100000"
}
},
{
"#columnnumber":"1",
"#name":"$149",
"number":
{
"0":119
}
}, etc...
You could implement your own REST service (or extension to existing one) in an extension library, but I guess you are looking for something easier.
Sorry no code, but maybe (and hopefully) an answer.
Have you looked at the xc:CalendarStoreCustomRestService custom control inside the Xpages Extension Library demo? It looks like they connected the calendar control with a normal JSON view store and that supports search en keys.
I found code you could use but you will have to extend the custom control. I think it is a new component that is not yet included as a xe: component inside the Extension Library.
This is how you use the control:
<xc:CalendarStoreCustomRestService id="cc4ccCalendarStoreCustomRestService"
storeComponentId="notesCalendarStore1" databaseName="#{sessionScope.databaseName}"
viewName="($Calendar)">
</xc:CalendarStoreCustomRestService>
This is your calendar component, it uses the above storeComponentId.
<xe:calendarView id="calendarView1" jsId="cview1"
summarize="false"
type="#{javascript: null == viewScope.calendarType? 'M' : viewScope.calendarType }"
storeComponentId="notesCalendarStore1">
<xe:this.loaded><![CDATA[${javascript:if (sessionScope.databaseName == null) {
return false;
} else {
return true;
}}]]></xe:this.loaded>
</xe:calendarView>
If you need some more info, this example is included inside the DWA_iNotesRest.xsp.
I googled a long time and the only solution I`ve found is to build your own Rest service
have you managed to filter the Calendar without this?