Add custom user information to twig service provider silex - twig

I am using the silex framework for my project. I am using the SecurityServiceProvider with a custom user implementation. The login/logout works and I am able to view the correct user information in the symfony profiler (stored as a session attribute). Now I am trying to add the custom user information to the twig environment so that is is accessible from the templates. Here is what I've come up with:
$app['twig'] = $app->share($app->extend('twig', function($twig, $app) {
$token = $app['security']->getToken();
$userInfo = null;
if (null !== $token) {
$userInfo = $token->getUser()->getTwigInfo();
}
$twig->addGlobal('userinfo', $userInfo);
return $twig;
}));
I am trying to extend the environment and it works, however the user information seems to be processed later and my userinfo attribute is always null. I guess that I have to somehow extend the twig environment later but do not know exactly how to do that. Can someone help me?

Silex gives you access to the app instance directly from Twig.
So you could do:
{{ app.security.token ? app.security.token.user.twigInfo : null }}
or
{% set userinfo = app.security.token ? app.security.token.user.twigInfo : null %}
{{ userinfo }}
If you prefer to handle it within your PHP code, then you can create a new definition
$app['userinfo'] = $app->share(function($app) {
$token = $app['security']->getToken();
return (null !== $token) ? $token->getUser()->getTwigInfo() : null;
}));
Then in your Twig template
{{ app.userinfo }}

Related

Variable Scope in ejs/express

So I am trying to sort out variable scope. Below is a simple snippet of code:
const params = {
versions: versions,
user: user,
statsParams: statsParams,
csrfToken: csurf.createToken(req),
};
res.render("server/edit", params);
return;
Now the values that are in the params object are available in the ejs page for use. What I am seeing is that other variables that precede this code block also seem to be available in the ejs file as well not just the ones passed via the param object. Is this expected behavior? I have looked on the ejs website and it doesn't speak of variable scope.
Brad
What you are doing with your code is rendering the page using ejs and passing the params object to the page. By passing it to the page you can render the page with access to the variables you passed in using the following tags : <%= variable =>
In terms of scope, you have now rendered the page to have access to all the variables you have passed in under the name params during the operation : res.render("server/edit", params);
If you have passed other variables through api calls to your backend you will also be able to access them in their according scope, but unless you include other variables to be passed as parameters you will not be able to access other variables from your backend.
Example :
--> userController.js
var outOfScope = True;
const params = {
versions: versions,
user: user,
statsParams: statsParams,
csrfToken: csurf.createToken(req),
};
res.render("index", params);
return;
--> index.html
...
<h1>Variable</h1>
<p><%= params.user %></p>
...
This will not work
...
<h1>Variable</h1>
<p><%= outOfScope %></p>
...
If you still have issues regarding access to variables you haven't passed it is possible you may have included them from another file by accident (ex. a header that is included).
I hope this helps, but if you are having trouble with specific variables please include them in your question as well as how you are accessing them.

How we can add session variables so we can use them in all templates?

How we can add a session in Grav and use that in all twig templates?
To set custom sessions in Grav and use those globally in all twig HTML templates, we can do so by setting the session globally in a controller.
In the plugin controller file
(In my case: user-plugins-pluginName-pluginName.php)
public static function getSubscribedEvents() {
return [
'onTwigExtensions' = ['onTwigExtensions', 0]
];
}
public function onTwigExtensions() {
require_once(__DIR__ . '/pluginName.php');
$this-grav['twig']-twig-addExtension(new PluginNameTwigExtension());
$this-grav['twig']-twig-addGlobal("session", $_SESSION);
}
Add session like this Globally and by doing this session could be used further in any of the twig templates.
Then, we need to set the session variable like
$_SESSION['key'] = $_POST['value'];
Now we can use this session value in any twig HTML template as:
{{ session.key }}

Passing XML and Outputting to Twig Template in SlimPHP 3

Currently using the SlimPHP 3 MVC framework and trying to XML output of a URL to the Twig template. I'm using the latest build of Guzzle if it helps.
I have my Controller set up and the function as follows:
public function getaws($request, $response, $args) {
$bucketname = $args['bucketname'];
$client = new \GuzzleHttp\Client();
$bucket = $client->request('GET', $bucketname . '.s3.amazonaws.com');
if($bucket) {
$buck = $bucket->getBody();
return $this->view->render($response, 'aws.twig', ['buck' => $buck]);
}
else {
$res = Array();
$res['message'] = 'Bucket Disabled or Unknown';
return $this->view->render($response, 'aws.twig', ['buck' => $res]);
}
}
In the Twig file - aws.twig I have only been able to output the entire XML response/body using:
{{ buck }}
I have tried typing:
{{ buck.Name }}
or
{{ buck.Key }}
Neither have worked. I've tried the ForEach loop as well and nothing comes from that at all. I'm completely at a loss. I've noticed that there doesn't seem to be an awful lot of help on SlimPHP but I like it and prefer using it to Laravel and no I won't switch to Laravel just to make life easier otherwise asking for help with this would be a waste of time.
Anyone who has had experience with SlimPHP 3, Twig templates and Guzzle - I'd very much like help with this.
Thanks!

Create a SharePoint Document Library with Microsoft Graph

I'm trying to create a new document library in a SharePoint Teams site using Microsoft Graph.
var docLibrary = $#"{{ ""name"": ""{listName}"", ""list"": {{ ""template"": ""documentLibrary"" }} }}";
var res = await GraphClient.QueryGraphAsyncPost($"/groups/{groupId}/sites/root/lists/", docLibrary, user);
var result = await res.Content.ReadAsStringAsync();
This is the code that I'm using, but it is returning a bad request. I can't seem to find in the documentation the correct way to create a Document Library.
You'll want to specify the displayName instead of the name. The value of name is generated by the server, and so the 400 is an error saying it cannot be written to. You should see an error response that contains the following message:
Cannot define a 'name' for a list as it is assigned by the server. Instead, provide 'displayName'
If you change your request to the following it should work:
var docLibrary = $#"{{ ""displayName"": ""{listName}"", ""list"": {{ ""template"": ""documentLibrary"" }} }}";
var res = await GraphClient.QueryGraphAsyncPost($"/groups/{groupId}/sites/root/lists", docLibrary, user);
var result = await res.Content.ReadAsStringAsync();

How to send some data of one template to another template Meteor

I want to share some data from template to another template using Meteor. I have a template i.e allInventory.html on which i am showing some data in table form i added three links there that is. one for view , edit and delete what i want iam getting all the data from backend into one of helper i.e productDetails and i bind an event with view button that will take the data of current user clicked on which product so i have successfully getting the data at my allinventory template but there is another template i.e productDetails on which i want to render or show that data. But stuck with that i have data on allInventory click event but not know how do ishare the same with productDetails template.
Here is my allInventory.js
Template.allInventory.rendered = function() {
Template.allInventory.events({
"click .btn":function (e){
data = $(e.target).attr('data');
Router.go('productDetail', {data: $(e.target).attr('data')}, {query: 'q=s', hash: 'hashFrag'});
console.log("button clicked.."+data);
console.log(data);
}
})
ProductDetails.js
Template.productDetail.rendered = function () {
Template.productDetail.helpers({
productDetails: function() {
return data;
}
});
allInvenrtory.html
<button type="button" data ="{{productInfo}}" class="btn btn-info btn-sm"><i class="fa fa-eye"></i>View</button>
I just simply want to share allInventory template data with productsDetails template.
Any help would be appriciated!
Thanks
I'd recommend avoiding Session for this purpose, since it is a global object, but more importantly, because there are better ways to do it.
You can pass data from the parent templates to the child template using helpers: https://guide.meteor.com/blaze.html#passing-template-content
You can pass data from the child to the parent templates using callbacks https://guide.meteor.com/blaze.html#pass-callbacks
I'd structure this app to have a container (page) template, which will have all the subscriptions and render one of your templates based on the URL.
You can use the Session variable if you want to share data between templates.
You can follow this guide:
http://meteortips.com/first-meteor-tutorial/sessions/
I would put both template in a third, parent template.
ParentTemplate
-SharedInfo
-KidTemplate1
-KidTemplate2
Then having this third template hold the information you want to share across templates.
For that you can use a ReactiveVar, ensuring that change by template1 code on the parent template is visible in template2 as well.
To access the parent template for the kids, you can do something along those lines :
Blaze.TemplateInstance.prototype.parentTemplate = function (levels) {
var view = Blaze.currentView;
if (typeof levels === "undefined") {
levels = 1;
}
while (view) {
if (view.name.substring(0, 9) === "Template." && !(levels--)) {
return view.templateInstance();
}
view = view.parentView;
}
};

Resources