Pass specific converters/templates to template with jsViews/jsRender - templates

I am trying to pass in converters and/or templates only to a specific template. According to the API you can only pass in helpers, but not converters or templates.
Is there any way to do this or does someone know if it is planned to support this in the future?
Note Passing them in globally via $.views.templates({...}) or $.views.converters({...}) is not really an option, because I will have way to many and perhaps even name-conflicting templates and converters.

You can declare converters with your templates - and they will be private to the template. See Registering templates: $.templates(). Look for "Advanced scenarios: Associating private resources with templates".
In addition, the API for registering converters: $.views.converters({...}) also allows you to register a converter (or a set of converters) either globally, or locally just for a specific template. See the section "Adding converters as private resources for a parent template". To make them local, or private, to a template, just pass in the template as last parameter in your converters() call.
So here is a template with its own special converter declared along with the template:
$.templates({
myTemplate: {
markup: "Use my converter {{myconv:name}}",
converters: {
myconv: function(val) { return myCalculatedValue; }
}
}
});
Now {{myconv:...}} is specific to myTemplate and won't be available elsewhere.
Now suppose I want to dynamically replace the "myconv", still just within myTemplate. I can add/change it at any time using the converters() API:
$.views.converters(
"myconv",
function(val) { return myNewUpdatedCalculatedValue; },
$.templates.myTemplate // Only override it for myTemplate, not globally...
);
Here are some related links:
http://www.jsviews.com/#samples/jsr/converters
http://www.jsviews.com/#samples/form-els/converters
http://www.jsviews.com/#samples/data-link/hover (This one declares a 'private' converter)

Related

C++ Unreal Engine encapsulate delegates

I'm new to unreal engine and c++. I have a class in which I define a delegate with one parameter and a return type:
DECLARE_DELEGATE_RetVal_OneParam(bool, FInteractionValidatorDelegate, APlayerController*)
I've added a property containing this delegate:
FInteractionValidatorDelegate Validator;
And in another class I bind the delegate:
SomeComponent->Validator.BindUObject(this, &AInteractable::IsValid)
This all works fine but I don't want to expose the delegate publicly thus I want to encapsulate it by adding a BindValidator() method to my component. What is the best method of doing this ?
you could write a function like this :
void yourComponent::BindValidator(UObject * obj, void(*func)(bool))
{
Validator.BindUObject(obj, func);
}
but I recommend against doing this, first because passing functions' pointers will make errors coming from this hard to find (delegates are already enough obfuscation, with lots of macros and generated functions), also you will not be able to expose this to blueprints.
In UE4's way of doing things you could just pass a delegate as a FName
like so :
void yourComponent::BindValidator(UObject * obj, FName functionName)
{
Validator.BindUFunction(obj, functionName);
}
Here it's the UE4 doing the functions' declaration matching.
Hope this helps!

liferay 7 jsonws API dlfileentry obc parameter example

I wanto to try the web service of dflservice entry into the web service portal
http://localhost:8080/api/jsonws
but the parameter used obc just explain as obc with the type com.liferay.portal.kernel.util.OrderByComparator, I try null, 0, +obc:com.liferay.portlet.documentlibrary.util.comparator.FolderNameComparator, but always have the same result:
Conversion failed: com.liferay.portal.kernel.util.OrderByComparator
What is the correct parameter
According to documentation:
You can't pass 0, as obc is an object type parameter.
To pass a null value for obc, you need to prefix it with a dash like: /-obc.
And to pass an instance of an object parameter, you need to prefix the parameter with a plus sign like: /+obc:com.liferay.portlet.documentlibrary.util.comparator.FolderNameComparator (Should work as well).
As com.liferay.portal.kernel.util.OrderByComparator is an abstract class, you need to pass a concrete implementation. Check the implementation of DLImpl.getRepositoryModelOrderByComparator method for further concrete implementations of OrderByComparator class for document library.
Also, I would like you to share the URI(s), you are trying. So, I can also try them.
Reference:
INVOKING JSON WEB SERVICES
Update:
There is bug in JSONWS GUI, which is already fixed in:
https://issues.liferay.com/browse/LPS-76955?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel
However, the URL access is working for me:
http://localhost:8080/api/jsonws/dlfileentry/get-file-entries/group-id/10184/folder-id/0/status/0/start/-1/end/-1/+obc:com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelNameComparator
Here, com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelNameComparator is a concrete implementation of obc.

Using preprocess hook on specific node type in Drupal 8

I've had success using preprocess page hooks such as:
function mytheme_preprocess_page__node_front(&$variables) {
...
}
and
function mytheme_preprocess_page__node_12(&$variables) {
...
}
which correlate with custom templates named page--front.html.twig and page--12.html.twig, respectively.
I'm trying to implement the same hook and template pairing for a content type called Video. I understand that there is a difference in that my examples have been custom templates for specific pages while my goal is a custom template for an entire content type, but I got a custom template called node--video.html.twig that works as a template for all video pages. However when I try to write a hook based on this template name:
function mytheme_preprocess_node__video(&$variables) {
...
}
this does not work. I think that I either can't define a hook like this, or I'm just naming it incorrectly. I found a couple threads somewhat relating to this such as this that seem to imply that I need to define a hook for all nodes and then write an if statement that handles each type separately.
So.......
Final Question: Can I define a hook for an entire content type, and if so what am I doing wrong?
Use condition within the preprocessor to get the node type and then either do your logic within, or invoke another function.
function mytheme_preprocess_node(&$variables) {
switch ($variables['node']->getType()) {
case "video":
// ...
break;
case "something_else":
// ...
break;
}
}
You could in theory emulate what you are trying to achieve by trying to invoke a function named mytheme_preprocess_node__" . $variables['node']->getType() if it exists, but is too much fuss without a clear benefit.
In drupal 7 from zen template I used to use this generic solution. I think it is still a viable solution on drupal 8:
function mytheme_preprocess_node(&$variables) {
...
// Add global modification that works for all node type
$function = __FUNCTION__ . '__' . $variables['node']->getType();
// Each node type can have its own specific function
if (function_exists($function)) {
$function($variables, $hook);
}
...
}
You can then now add preprocess function that will only works for you node type.
function mytheme_preprocess_node__video(&$variables) {
...
}
Instead of having one big function, each node type's preprocess logic has its own function. It's better for maintainability.

Silverstripe Template Issue

I'm getting to grips with the Silverstripe framework and I've come across a strange error.
Say for example I want to create a new 'membership' page. Within mysite/code I have set up a membership.php page as follows:
class Membership extends Page {
}
class Membership_Controller extends Page_Controller {
}
Then I have created a membership.ss file within my templates/layout folder with some test output. I then do a dev build and create a page in the CMS of type 'membership'. On the front end if I click the new page form the nav bar membership I don't see the test text so it seems that the template is not being read?
Any ideas?
Thanks.
Alan.
There are several common pitfalls regarding templates:
how flushing works has changed several times in the past versions.
I will not explain the details here, as those are prossibly subject to change soon again.
However there are 2 things in the current version (3.1) that is of relevance here:
/dev/build does NOT flush at all
/dev/build?flush=1 does ONLY flush manifest and config (NO templates)
(dev build does not use the template, so there is no flushing the template performed)
this means that you have do do a ?flush=1 on a normal page, not just on dev/build
The Template file has to be named exactly like the class (I think its case sensitive)
check that the template file is not overwritten by another template file in another location. (eg if you have moduleName/templates/Foo.ss and themes/simple/templates/Foo.ss than the template of the theme will overwrite the module template
make sure the template is not empty (this causes an error in SilverStripe, at least in version 3.1)
Actions on a Controller can overwrite template ussage. here some examples:
// this will not use a template at all, it will just print "some string"
public function index() { return "some string"; }
// this will not use a template at all, it will output an empty string
public function index() { return; }
// this will use template named "Bar.ss"
public function index() { return $this->renderWith(array('Bar')); }
SilverStripe also provides a debug option to see what templates are used.
you can active it by 2 ways:
set source_file_comments in your yml config:
SSViewer:
# display template filenames as comments in the html output
source_file_comments: true
use the "URL Variable Tools": just add ?showtemplate=1 when viewing your website
when enabled, see the HTML source (CTRL+u in firefox) of the page
silverstripe will add comments to let you know what templates are used.
Make sure your class has a Page_Controller extension declared and named correctly. I recently had this issue. The page controller extension had a typo, so the template file was not being used.
So for example, if your page class is RidiculouslyNamedPage
class RidiculouslyNamedPage extends Page {
}
class RidiculouslyNamedPage_Controller extends Page_Controller {
}
Then in your themes/[theme-name]/templates/Layout/ folder you would have your RidiculouslyNamedPage.ss.
If you misspell RidiculouslyNamedPage_Controller the template will not get called.
I found the answer to the problem.
My .php was missing the following:
function getInfo() {
return $this->renderWith('Media');
}
ithout this the Media.ss file will not be used! Hopefully this will help other who might be getting to grips with SS!

Request context in a Go template

I would like to write such a conditional fragment in a Go HTML template :
{{if isUserAdmin}}
<a href"/admin/nuke">Go to the big red nuclear button</a>
{{end}}
However, this is not directly possible because the template is not aware of the request that triggered its execution, so it cannot determine if the user is admin or not.
Is there some normal way to achieve this ?
In advance I point out that :
I do not want to use Pipelines for this specific data (see other question about this)
I acknowledge that only the handlers/controllers should deal with logic, and views should only do the rendering. But the condition {{if isUserAdmin}} is not logic itself, it's a necessary construct to leverage a boolean value already calculated by the controller.
The Funcs method can help, but is currently not lean enough for easily defining specific method isUserAdmin()
I would agree with Darshan Computing, I think the proper way of passing information from the request would be in the pipeline. You can have your data being split between the data you want to render and the context, e.g. by having your template data structure embed them both if you want to clearly separate the two:
type TemplateData struct {
*Content
*Context
}
Which gives this for example. You can then reuse some of your context/content information depending on what is shared and what is query specific.
Here is a working solution attempt (link to Playground) using Funcs to overwrite "isAdmin", after template compilation but before each execution (thanks to Valentin CLEMENT in other question).
But it has several flaws :
It is weird to declare a dummy empty "isAdmin" function before template compilation.
(Using Funcs several times is painful because I cannot just overwrite a single method, I have to provide a complete FuncMap with all the functions) edit : in fact previous funcs are not lost, i was wrong about that.
It is inherently not thread-safe and will fail when several goroutines alter and execute the same template
The normal thing to do is to simply pass your template a struct with whatever static data you like. Unless I've misunderstood what you're trying to do, there doesn't seem to be any need for Funcs here. Simplifying your example:
package main
import (
"html/template"
"os"
)
const hometmpl = `
{{if .IsAdmin}}
Go to the big red nuclear button
{{end}}
`
var t = template.Must(template.New("home").Parse(hometmpl))
func isAdmin(token string) bool {
const adminToken = "0xCAFEBABE"
return token == adminToken
}
func main() {
token := "0xCAFEBABE" // Or extracted from the http.Request
t.ExecuteTemplate(os.Stdout, "home", struct{IsAdmin bool}{isAdmin(token)})
}