Is there a Django's context processor like in Grails? - grails

I want to output a value which is global in all the templates or even layout in Grails, like Django's context processor where you could render the context and use it as global variable in the templates.
Is there a concept like this in Grails? And, how can I use that in the layout?

I am not familiar with Django at all. Looked up Django's context processor in google, I think I get it. Basically it configures reusable data that gets injected into every template? Anyway, as far as I know nothing like that exists in Grails. You can try the following as a workaround.
Use ApplicationContext
Every view has access to the applicationContext. So make a service that holds all the data you need, let's say it is called fooService, and the data item you want is a field in the service called bar (could be a method too of course). Then in your view do ${applicationContext.fooService.bar}. Resource for accessing applicationContext in view: http://mrhaki.blogspot.com/2011/11/grails-goodness-get-grailsapplication.html.
Use your layout
I am not sure about this one, so use at your own risk. The top one is of course extremely verbose. It would be annoying to call that over and over again in different views. So instead, call it once and make it a variable in your layout with g:set. I think the variable will be available in every view that uses that layout.... but not sure. Here are the docs for g:set -> http://grails.org/doc/latest/ref/Tags/set.html.
If I didn't get what context processors do in python I am happy to try again...

Related

Can I make a razor file optionally be a template file (RenderBody or RenderSection)

When I have RenderBody or RenderSection, and I try to use a template directly, it gives an error:
The file "~/Views/Home/Form.cshtml" cannot be requested directly because it calls the "RenderSection" method.
I have a form that has some basic fields, but in one instance, I want to extend the form with more fields (the Model inherits from the original).
Maybe I should just create the basic fields in a shared file, but this would work if it wouldn't throw the error above...
In Razor, everything is a view. "Partial views" are just views that don't utilize a layout, while the more traditional "views" are views that do. A "layout" is merely a view that at least calls one method, RenderBody. RenderSection, is likewise layout-specific. By making a view a layout (by calling methods like RenderBody, RenderSection, etc., it can no longer be used as "view" or "partial". This has to do with the way Razor handles view processing. By the time something like a partial is being rendered, there's nothing that can be done with something like RenderBody, so Razor raises an exception.
Long and short, you can't use a layout as a partial, which seems to be what you're trying to do here. Without more information about what it is that you're actually trying to achieve, it's not really possible to help you further than that.

With grails, can I specify the controller, action, and view in UrlMappings.groovy?

With Grails, in UrlMappings.groovy, it seems I can specify the controller and action:
"/someURL" (controller: "Some", action: "someAction")
Or I can specify the view:
"/someURL" (view: "someView")
But I can't specify the controller, action, and view:
"/someURL" (controller: "Some", action: "someAction", view: "someView")
Instead, I have to specify the view in the controller. Is there a way to specify the view in the UrlMappings.groovy? Or is it just not possible?
To do this, you would first need to know that Grails uses Spring Web under the hood. Spring Web is the most complex web framework I can think of (capable of doing anything AFAIK). At any rate, the important thing to know is how Spring Web's Request Life Cycle works. You can get a feel for it by reading the documentation of the "DispatcherServlet" which is the main Servlet in Spring Web (and consequently in Grails):
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/DispatcherServlet.html
Here is a great article from the grails team about how grails is really just spring:
http://spring.io/blog/2010/06/08/spring-the-foundation-for-grails/
The important part relevant to this question are these two lines from that documentation:
Its view resolution strategy can be specified via a ViewResolver implementation, resolving symbolic view names into View objects. Default is InternalResourceViewResolver. ViewResolver objects can be added as beans in the application context, overriding the default ViewResolver. ViewResolvers can be given any bean name (they are tested by type).
If a View or view name is not supplied by the user, then the configured RequestToViewNameTranslator will translate the current request into a view name. The corresponding bean name is "viewNameTranslator"; the default is DefaultRequestToViewNameTranslator.
What you really want to do is create a customized ViewResolver or RequestToViewNameTranslator. The world is quite complex - if a View is supplied by the user in the Grails Controller explicitly, then you would want a ViewResolver. If instead a Map is returned (or some other custom object), then you want a RequestToViewNameTranslator.
Don't forget that grails has customized these two things already, to use the whole "convention over configuration" idea. So, you have to be careful in how you implement yours - I would recommend looking at the grails default implementations of these things.
Source for the GrailsViewResolver is here:
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/view/GrailsViewResolver.java
Now, the real fun begins. The grails team didn't just provide custom implementations of spring web's default life cycle, they completely customized the dispatcher servlet as well. This means you need to be aware of how their universe differs from the spring universe (thus rendering many helpful spring forum questions irrelevant). Here is a link to the GrailsDispatcherServlet source code:
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/servlet/GrailsDispatcherServlet.java
So if you managed to read this far, you can probably envision how to write a customized view resolver to return the view you want, but how to get access to the URL Mappings configuration data, so you can define views in there (however you see fit). The UrlMappings file relates to a spring bean, which will be available to autowire using the property "grailsUrlMappingsHolderBean" - see http://grails.org/doc/2.3.4/ref/Plug-ins/URL%20mappings.html
From that bean, you can access UrlMappings object, which you can get access to all UrlMapping definitions. See:
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMappings.java
https://github.com/grails/grails-core/blob/master/grails-web/src/main/groovy/org/codehaus/groovy/grails/web/mapping/UrlMapping.java
I'm not entirely convinced whether you can just throw anything in there, but since it's groovy I'd think you can. If not, you would have at least 2 options:
Create a new config file for just controller/view mappings your custom view/viewname resolver would use
Customize the URLMappings based on the grails source to interpret your custom configuration
A little off topic, here is an interesting article about removing the default mappings file and home-rolling your own:
http://mrhaki.blogspot.com/2011/12/grails-goodness-customize-url-format.html
Again, I found several posts online where people went down this path, and it ended up being too hard because of the numerous configuration pieces need to make it function. Thus, I highly recommend against it. To a certain degree, I agree with the response on this page (which is what you will see alot trying to do something out of the grails universe):
Bypassing grails view resolvers?

Why use instance variables to "connect" controllers with views?

This is a conceptual question and I haven't been able to find the answer in SO, so here I go:
Why instance variables are used to connect controllers and views? Don't we have two different objects of two different classes (Controller vs Views). So, when the view is rendered we are in a different context, but we are using instance variables of another object? Isn't this breaking encapsulation in somehow?
How does Rails manage to do that matching from one object to another? Does it clone all the instances variables of the controller to the view?
In a sense, you could say that it is breaking encapsulation. I have found that if you are not careful, it is easy to get your business/presentation logic mixed together in Rails. It usually starts when I am writing a view template, and discover that I need some value which I didn't pass from the controller. So I go back, and tweak the controller to suit what I need in the view. After one tweak, and another, and another, you look at the controller method, and it is setting all kinds of instance variables which don't make sense unless you look at the view to see what they are for. So you end up in a situation where you need to look at both controller and view to understand either, rather than being able to take one or the other in isolation.
I think that using instance variables (together with the Binding trick) is simply a way to pass whatever values you need from controller to view, without having to declare parameters in advance (as you would when defining a method). No declarations means less code to write, and less to change when you want to refactor and reorganize things.
Rails uses eval and Binding to pass controller instance variables to views. See this presentation from Dave Thomas, there's a small example at minute 46' that explains how this is done.

Ninject binding/unbind issue

I have a bit of a dilemma, which to be honest is a fringe case but still poses an issue.
Currently I am using Ninject MVC and bind all my controllers like so:
Kernel.Bind<SomeController>.ToSelf();
Which works a treat for 99% of things that I have needed to do, however at the moment I am doing some wacky stuff around dynamic routing and dynamic controllers which require me to manually write a method to get the type of a controller from ninject. Now initially I thought it would be easy, but its not... I was expecting that I could get the controller based on its name, but that didnt work.
Kernel.Get<IController>("SomeController");
That got me thinking that its probably because it only knows about a binding to SomeController, not IController. So I thought, I can just write all my bindings like so:
Kernel.Bind<IController>.To<SomeController>().Named("SomeController");
This way it should be easy to get the type of the controller from the name doing the previous code, however if I were to bind this way, I would have a problem when I come to unbind the controllers (as plugins can be loaded and unloaded at runtime). So the normal:
Kernel.Unbind<SomeController>()
Which was great, will no longer work, and I would have to do:
Kernel.Unbind<IController>();
However then I realised that I need to give it some constraint to tell it which binding for this type I want to unbind, and there seems to be no overloads or DSL available to do this...
So I am trapped between a rock and a hard place, as I need to satisfy the ControllerLookup method, but also need to keep it so I can add and remove bindings easily at runtime.
protected override Type GetControllerType(RequestContext requestContext, string controllerName) {
//... find and return type from ninject
}
Anyone have any ideas?
(Just incase anyone questions why I am doing this, its because of the way I am loading plugins, Ninject knows about the types and the namespaces, but within the context of creating a controller it doesn't know the namespace just the controller name, so I do this to satisfy the isolation of the plugin, and the location of the dynamic controller, it is a roundabout way of doing it, but it is what people have done with AutoFac before Example of similar thing with AutoFac)
In my opinion the bindings should be created once at application startup and not change anymore after the first resolve. Everything else can lead to strange issues. Unless you have proper isolation using an AppDomain for each plugin you can not really unload them anyway. Instead of unloading bindings you can make them conditional and disable them using some configuration.
If you really want to unload bindings then I suggest not to do it for single bindings but take advantage of modules. Load all bindings belonging to one plugin together in one or several modules and unload those modules instead of the single bindings.

Entity Framework context

I have an application using the Entity Framework code first. My setup is that I have a core service which all other services inherit from. The core service contains the following code:
public static DatabaseContext db = new DatabaseContext();
public CoreService()
{
db.Database.Initialize(force: false);
}
Then, another class will inherit from CoreService and when it needs to query the database will just run some code such as:
db.Products.Where(blah => blah.IsEnabled);
However, I seem to be getting conflicting stories as to which is best.
Some people advise NOT to do what I'm doing.
Other people say that you should define the context for each class (rather than use a base class to instantiate it)
Others say that for EVERY database call, I should wrap it in a using block. I've never seen this in any of the examples from Microsoft.
Can anyone clarify?
I'm currently at a point where refactoring is possible and quite quick, so I'd like some general advice if possible.
You should wrap one context per web request. Hold it open for as long as you need it, then get rid of it when you are finished. That's what the using is for.
Do NOT wrap up your context in a Singleton. That is not a good idea.
If you are working with clients like WinForms then I think you would wrap the context around each form but that's not my area.
Also, make sure you know when you are going to be actually executing against your datasource so you don't end up enumerating multiple times when you might only need to do so once to work with the results.
Lastly, you have seen this practice from MS as lots of the ADO stuff supports being wrapped in a using but hardly anyone realises this.
I suggest to use design principle "prefer composition over inheritance".
You can have the reference of the database context in your base class.
Implement a singleton for getting the DataContext and assign the datacontext to this reference.
The conflicts you get are not related to sharing the context between classes but are caused by the static declaration of your context. If you make the context an instance field of your service class, so that every service instance gets its own context, there should be no issues.
The using pattern you mention is not required but instead you should make sure that context.Dispose() is called at the service disposal.

Resources