I've been getting into Pylons lately and was wondering how I could go about easily integrating AJAX functionality into my websites.
Basically, lets say I had a login form that usually gets accessed via site.com/user/login. Now, generally, this will be handled via something like:
class UserController(BaseController):
def login(self):
render('/login.html')
login.html would be a template that inherits the base, has a header, footer and navigation sidebar. A plani, simple website.
How could I AJAXify this? I would need to create two login.html templates, right? What would be a good way to handle the controller's login() method? Should I set a GET variable of something like &ajax=true then check for that when issuing render()?
I want a nice and clean way to choose how my controllers render content instead of some ugly hack (like the GET method above).
Thoughts?
All modern Javascript libraries set an "X-Requested-With: XMLHttpRequest" header in their AJAX wrappers. As a convenience, Pylons sets the request.is_xhr boolean if it finds this header.
Conditional inheritance is a little tricky in Mako because of how <%inherit> is handled, but here's what you do:
Change the render() call in your controller to render('/login.html', {'ajax': request.is_xhr})
In your template, separate out anything you don't want in your AJAX template using template inheritance.
Use an <%inherit> something like this:
<%inherit file="${None if context.get('ajax') else 'login_base.html'}"/>
(Note: There's nothing special about the render() syntax used. You could just as easily use c.ajax = request.is_xhr and context.get('c').ajax instead)
I'm not sure why your AJAX code would want to do a GET on that login page -- GET is only for getting information, and what info would the JS code client-side want to obtain from a login form?
Anyway, assuming there are pages that you want AJAX code to be able to GET in order to obtain useful info, I recommend a query string such as ?format=json to allow such requests to explicitly ask for "useful JSON-format info only, no decoration please".
Not only does this approach allow your app to know that this is an automated request (AJAX or otherwise, who cares? point is, no cosmetics are to be sent in response, just useful info!) but specifically that the requested format is JSON (so, should you ever want to supply XML or whatever as an alternative, there's an obvious growth path -- ?format=xml and the like).
There is nothing particularly Python-specific, much less Pylons-specific, in this -- it's the approach I would recommend for any "mixed" site (able, at least in some pages, to respond in more than one format, e.g. HTML with decorations or JSON, at clients' choice) no matter what sever-side language it was planning on using.
If your rendering is always of a form such as somefunction(sometemplate, somecontext), though, you may tweak things to ensure that the somefunction also gets the crucial bit about requested format -- if the requested format is JSON (or, who knows, in the future maybe XML or whatever) then somefunction knows it can ignore the template (which after all is or should be a purely view related functionality, and therefore should have presentation contents only) and just proceed to render the info that's in the context as JSON or whatever.
The author of Mako himself wrote a blog post that you might find interesting.
The main point is a function to render a single "def" of a template:
def render_def(template_name, name, **kwargs):
from pylons.templating import pylons_globals
globs = pylons_globals()
if kwargs:
globs = globs.copy()
globs.update(kwargs)
template = globs['app_globals'].mako_lookup.get_template(template_name).get_def(name)
return template.render(**globs)
Related
I'm playing around with NestJs, for the purpose of automating REST API creation as much as possible. So far, I do not see any quick way to create a fully functional resource.
For example, if I use the Nest CLI like this:
nest g resource
And call my resource "posts", I get a module, a controller, a service, dto's and an empty entity
In order to make it functional, I would need to manually go through every method of the PostsService, remove the placeholder, and wire it to the corresponding entity method. For example, this needs to be altered:
findAll() {
return `This action returns all posts`;
}
to:
findAll(){
return this.postsRepository.find()
}
Not to mention, that I need to add various decorators and imports. In my opinion, this undermines the whole idea of CRUD generator. A lot of files are created for me, but they need to be altered.
Is there any way in Nest to create a fully functioning resource(of course i would still need to manually set the fields of the entity), with all parts wired to each other correctly?
I also tried to find something similar. And this is the best what I found https://github.com/ashinzekene/generator-nestjs-app
I think if such a thing existed, then it should have been mentioned in this repository. https://github.com/nestjs/awesome-nestjs
But it's not. Maybe I'm wrong 😑
The purpose of nest isnt to get up and running asap -> You would probably want to use something a little bit more user friendly / or one with a more guided workflow.
in terms of what the generator is giving you...
Controller Only deals with the request / response being recieved and sent... it doesnt have any other type of functionality...
DTO think of it like an interface but with more functionality , as you can add data-validation / etc to make sure the request object is formated properly...
Service Exposes the methods that contain all of our business logic. for a crud app, this would be where your actual get post put patch delete would be ... and how the data us modified in your db. Then once this finishes it would return the response if any to the controller which sends the info out.
this is helpful for many reasons... one if our project has 200 endpoints and 40 people working in different teams you dont want each team to have a different way of doing things, also you want it to be clear where each thing is... if you endpoints need to be changed , you simply go to your controller... if the logic needs to change, you go to that service etc...
The Purpose of nest is to give you a framework for extremely modular apps / essentially everything decoupled..
think of it in terms of an express... you could have a single page express app that just has everything in one place... or you could have every single thing on it's own area...
esentially nest doesnt do anything crazy that express cant, it's just the underlying inversion of control (the .main file which calls the app.module which builds all the different pieces that are needed for that endpoint / app / service / or etc.)
If you just want to use nest because it seems shiny , id consider looking up something like fastify or / even appsmith / or something else like that...
I'm a newbie when it comes to PHP. I wrote some JS to make AJAX requests for my project and it worked well, but I don't have any idea how to convert that into PHP.
I've prepared layouts like the following:
mainLayout.php,
userLayout.php,
offerLayout.php,
In those files are some PHP and MySQL parts that build an HTML page.
In Ajax it was easy to navigate between many users using only one page and replacing some divs with data...
But a huge minus was that you couldn't have a single address reference a user profile or the offer (like mywebsite.com/user1).
Now, when I use PHP I want to achieve same layout effect.
How can I avoid creating a thousands of pages (of course even dynamically it seems to be a waste of memory IMO) like user1.php, user2.php, offer1.php, etc.
I don't know how to achieve the effect of being on a site like example.com/user277373.php without creating thousands of files but only one template.
Two solutions I see is either you use GET to parse your data:
http://example.com/?data=1736861
and than access it over the $_GET variable:
$id = $_GET["data"];
($id will be 1736861)
or you use the flight php extension, that will look something like this:
Flight::route('/id/#id', function($id){
echo "ID: $id";
});
and the URL would look like http://example.com/id/1736861. You can also use multiple variables with the flight module.
I hope this helped, Sebastian
Are you familiar with any MVC frameworks? If not, I would highly recommend getting accustomed to the MVC design paradigm. MVC = Model View Controller. From Wikipedia, a short excerpt:
A model stores data that is retrieved according to commands from the controller and displayed in the view.
A view generates new output to the user based on changes in the model.
A controller can send commands to the model to update the model's state (e.g., editing a document). It can also send commands to its
associated view to change the view's presentation of the model (e.g.,
scrolling through a document).
Two of the key components of MANY frameworks (in pretty much any language), are Routes and Templates. When utilizing a routing system, you're able to specify a template for every page loaded that matches a specific route. For instance, site.com/people/:id where ':id' can be any value in the URL, and be configured to use "person.html" for the HTML output. Note that "person.html" receives variables/data that will dynamically populate content, e.g. <h2>Hello, {{name}}</h2>
So, to clarify, site.com/people/252, site.com/people/12, site.com/people/5, site.com/people/john would all match the site.com/people/:id route path where :id is dynamic, and your system will use ONE TEMPLATE (which you specify) to display all the data. Don't forget, when that route path is met, that's only step 1. You will probably need to take that :id run some database query and pass that data into the template.
A popular micro PHP framework called Slim, might be a good starting point. Here's documentation for its way of handling Routes and Templates:
https://www.slimframework.com/docs/objects/router.html
https://www.slimframework.com/docs/features/templates.html
Slim is commonly used with Twig, a super popular PHP template engine. Here's its website/documentation: http://twig.sensiolabs.org/
And if that wasn't enough, Slim has a super handy First App Walkthrough that will show you routes, database connection, and templates: https://www.slimframework.com/docs/tutorial/first-app.html
Hope this information helps you on your journey – Best of luck!
Ok so I've build a little php MVC framework. It basically has the following layers:
controllers: handling input, calling functions from the services based on that input and usually forwarding variables to the view (and rendering it)
domain-layer: split up into...
...models: domain entities, basically just setters and getters validating data and providing a consistent
data interface for the views
...mappers: loading/storing models
from/to the database
...services: encapsulating domain logic, like
"registerUser" or "sendMessage"
views: basically just html with some php.
Ok so far this works well. However now I would like to add some javascript functionality. I'm not sure how to do this properly. I know I'm supposed to send post-requests to my php scripts, but my controllers f.e. are not providing any return values, but instead just output views. So if I wanted to retrieve a list of friends for a user with js, would I..
a) provide a "javascript access service", which handles javascript requests with help from the domain services and outputs the results as json? What I wouldnt like about this, is that it leads to redundancy in some of my requests. I might have a regular controller action for viewFriends() and now I would have to add a javascriptService->viewFriends() as well.
b) have all my controllers return results? I don't even think this is really possible, cause javascript can only store whats being echoed, right?
Whats the way to go here?
Thanks.
If I was you I'd consider what a view is, and then make some minor changes to your controllers to enable them to output views that are not just HTML - so for example you might want to output some JSON data - and this could be considered a view.
This tutorial - http://www.paulund.co.uk/use-php-to-detect-an-ajax-request shows how to check if a request is Ajax - so you could use this method in the controller to decide how you want to deliver a view etc.
A question regarding ng-bind-html whilst upgrading an Angular app from 1.0.8 to 1.2.8:
I have locale strings stored in files named en_GB.json, fr_FR.json, etc. So far, I have allowed the use of HTML within the locale strings to allow the team writing the localized content to apply basic styling or adding inline anchor tags. This would result in the following example JSON:
{
"changesLater": "<strong>Don't forget</strong> that you can always make changes later."
"errorEmailExists": "That email address already exists, please sign in to continue."
}
When using these strings with ng-bind-html="myStr", I understand that I now need to use $sce.trustAsHtml(myStr). I could even write a filter as suggested in this StackOverflow answer which would result in using ng-bind-html="myStr | unsafe".
Questions:
By doing something like this, is my app now insecure? And if so, how might an attacker exploit this?
I can understand potential exploits if the source of the displayed HTML string was a user (ie. blog post-style comments that will be displayed to other users), but would my app really be at risk if I'm only displaying HTML from a JSON file hosted on the same domain?
Is there any other way I should be looking to achieve the marking-up of externally loaded content strings in an angular app?
You are not making your app any less secure. You were already inserting HTML in your page with the old method of ng-bind-html-unsafe. You are still doing the same thing, except now you have to explicitly trust the source of the HTML rather than just specifying that part of your template can output raw HTML. Requiring the use of $sce makes it harder to accidentally accept raw HTML from an untrusted source - in the old method where you only declared the trust in the template, bad input might make its way into your model in ways you didn't think of.
If the content comes from your domain, or a domain you control, then you're safe - at least as safe as you can be. If someone is somehow able to highjack the payload of a response from your own domain, then your security is already all manner of screwed. Note, however, you should definitely not ever call $sce.trustAsHtml on content that comes from a domain that isn't yours.
Apart from maintainability concerns, I don't see anything wrong with the way you're doing it. Having a ton of HTML live in a JSON file is maybe not ideal, but as long as the markup is reasonably semantic and not too dense, I think it's fine. If the markup becomes significantly more complex, I'd consider splitting it into separate angular template files or directives as needed, rather than trying to manage a bunch of markup wrapped in JSON strings.
A psuedo controller method
#RequestMapping("/foo")
public String getFoo(Model model) {
model.add("foo", repo.findFoo());
model.add("bar", repo.findBar());
model.add("barOptions", repo.findBarOptions(bar));
return "fooView";
}
Let's say the client uses Expression language to render foo and bar; but we use JavaScript to render barOptions.
<html>
<script>
var options = <mytag:toJSON object="${barOptions}"/>;
$("#options").renderOptions( options );
</script>
<body>
<mytag:renderFoo foo="${foo}"/>
<mytag:renderBar foo="${bar}"/>
<ul id="options"></ul>
</body>
</html>
Common conventions tells me this is bad. But the essence of MVC, where the controller sends data and the view determines how to use it, tells me this is good. Is there a better way to do the same thing? Is there any reason why this isn't commonly done? I could request the JSON using a separate call, but then I have to make more requests for the page to load, and there may be logic to determine barOptions in the controller method getFoo() based on other input at the time of the page load.
At first glance I can not say that I see anything blatantly wrong with approach. The only aspect that initially took me off guard was your need to convert data in the model object to json.
For me, JSON usually implies that there is some sort of server side object that needs to be converted so that a client side javascript can access or manipulate its structure in a javascript way. I guess without knowing more of the purpose of the options list, I can't see a reason why json serialization is required here.
By using a Tag to convert a model object to JSON, we avoid an
additional request made by the client
But if we assume that JSON is a requirement (perhaps for some third party jquery plugin), then I absolutely do not see anything wrong with approach.
What is special or different about the barOptions unordered list, why does it have be rendered with json? Why not just use a for loop to build the list items? Or you can have a custom tag that builds out the ul entirely.
Aside from that, I missing the point as how one may perceive this as being bad code.
Normally JSON is requested by JavaScript with an Ajax call, but if in your case it's available at page rendering time, I see nothing wrong with your solution. It's clean, compact code and easy to read. Looks perfectly OK to me, the alternative would be to loop on the options array with a forEach, but this approach looks better.