Im having some conflicts with the Searchable plugin.
I have a filter which fetches the controller in question in the before phase. It fetches the requested controller by finding the first controller that has the same name as controllerName which is a property available in grails filters.
however, my problem is that the Searchable plugin has its own SearchableController, and i myself have made my own version of the SearchableController. The effect of this is that i have two classes with the same name that would match controllerName in my find logic.
controller = grailsApplication.controllerClasses.find { c ->
c.logicalPropertyName == controllerName
}
Can i somehow remove the SearchableController that comes with the plugin? What are my options?
Maybe this could help you:
http://grails.org/Searchable+Plugin+-+SearchableController+and+view
I found an existing post on this topic:
Disable grails Searchable plugin default search page?
I worked around the issue by renaming my SearchableController class to SearchController. Don't like workarounds tho...
Related
I'm new to Sitecore MVC and currently with web forms I have all the sites organized under:
\Website\Sites\Site1\css|js|Layouts|Sublayouts|etc.
\Website\Sites\Site{n}\css|js|Layouts|Sublayouts|etc.
I'm able to add an MVC site to my solution and works fine alongside the web forms sites; however, adding a second MVC site that happen to have the same controller/view names generates a conflict.
For example, if I create a controller for Site1
Controllers/Site1/FooController (has index and hello)
Then the views are:
Views/Foo/Index
Views/Foo/Hello
But if Site2 also has a controller with the same name then it's a conflict:
Controllers/Site2/FooController (has index and hello)
Then the views are:
Views/Foo/Index
Views/Foo/Hello
But they're used by Site1.
The question is how to setup two (or more) MVC sites that happen to have the same controller/view names. Is there a recommended way to structure the sites in the solution or do I have to override pipelines/processors?
Thanks
Update:
Thanks everyone. Areas solved my problem but introduced two new problems:
The conflict in the controller names which solved by putting the namespace, class and dll names in the controller name in Sitecore - reference: http://blog.xcentium.com/2014/03/sitecore-mvc-and-duplicate-controller-names/
When the controller returns a view, I have to put the full path of the view; otherwise, I get an error where the view is not found.
For example: return View("~/Areas/Site1/Views/Home/Index.cshtml");
I'm looking into a fix provided from a developer from Sitecore's forum:
http://www.chrisvandesteeg.nl/2014/06/13/sitecore-mvc-in-a-multisite-environment-areas/
I'll try it out and report back.
you need to use namespaces in routes.MapRoute, look at the below posts which have already discussed:
Is it possible, in MVC3, to have the same controller name in different areas?
Multiple MVC projects in a single solution
and below is the post by John west post which relates your situation:
http://www.sitecore.net/Community/Technical-Blogs/John-West-Sitecore-Blog/Posts/2012/06/Using-Web-Forms-and-MVC-in-a-Single-Solution-with-the-Sitecore-ASPNET-CMS.aspx
We had the similar problem and answer was to separate out every site with MVC areas and they works perfectly. Though we ran into issue of controller name duplication but that can be resolved by adding the namespace during the area route registration.
But a clean way to implement this is to let Sitecore know about the MVC areas and initialize your controller/action with area and namespace. This process has been blogged by Kevin and he has a package as well. It expect you to define the area name in controller rendering.
http://webcmd.wordpress.com/2013/01/24/sitecore-mvc-area-controller-rendering-type/
To avoid the hard coded path of view(s) you can always extend controller rendering template to add view path and create an action filter to add the view path after action is executed. Add the below code in action filter and register the filter in sitecore action filter registration pipeline.
public void OnActionExecuted(ActionExecutedContext filterContext)
{
ViewResult result= filterContext.Result as ViewResult;
if(result == null) return;
Rendering redering = RenderingContext.CurrentOrNull.With(x=>x.Rendering).Return(x=>x,null);
string viewName= rendering.Return(r=> r.GetFieldValue(CustomMvcSettings.ViewPathField), string.Empty);
if(String.IsnullOrEmpty(viewName)) return;
result.ViewName = viewName;
}
The best thing you can do is split your websites up in different projects in the same solution.
Building two websites in the same project can become unstructured and messy.
After that you can route the controllers with the same name using the different namespaces.
Sitecore mvc duplicate controller
Just to keep this topic in sync with the SDN forum,
I recommend using a sitecore specific constraint, as described at
http://www.chrisvandesteeg.nl/2014/06/13/sitecore-mvc-in-a-multisite-environment-areas/
This solution allows you to set the attribute mvcArea on your configuration node
I have created several controllers in my Grails project and put data for each controller in the bootstrap, but the data does not appear in the table for each controller that scaffold provides as the default view. I have checked inside dbconsole to be certain that the data is there, which it is. I have also refreshed the dependencies to make certain that the version of the scaffolding plugin is not corrupted. I am using Grails 2.3.5 and Scaffolding 2.0.1.Are there any suggestions of what could be wrong?
class DepartmentController {
static scaffold=Department
def index() { }
}
Looking back at other examples of using scaffolding I realize now that I should have taken out the index portion of the code, even though it is empty.
Remove your the index method and make it like this:
class DepartmentController {
static scaffold=Department
}
Put some log messages into the controllers (or debug the app) right after the controller loads the data using the domain class in order to see if the query has resulted in any domain instances.
If not, activate sql logging and check the exact select statement executed. Possibly you have something wrong in your domain mapping so a wrong select stmt is sent to the db
I'm new to Grails and am trying to build a CMS with it.
I want the navigation menu to read from the database so a new page will automatically get a link in the navigation. I've been reading Grails: use controller from index.gsp and related questions, but the answers don't seem to work for me. :(
I've created a domain class named Navigation and a template called _header.
In the "Navigation/list" namespace everything works fine, but outside I can't get to the Navigation data.
I've setup url mapping like so:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}
"/"(controller : "Navigation", action : "list")
"/"(view:"/index")
"500"(view:'/error')
}
}
But that doesn't seem to work. Any clues on what could be the problem?
You have two mappings for "/", your new one and the original one: "/"(view:"/index") - for starters you'll need to remove the other one.
Not sure if you are aware of this, but there is an open source CMS built in Grails called Weceem. If you need to use it as part of another Grails application, there is also a grails plug in for Weceem, so you can use it as part of your app.
It might worth looking into it before building a complete new CMS :-)
I was looking at the problem all wrong, urlmapping only made the index.gsp redirect to navigation/list. What I was looking for was the
DomainClass.findAll( String query )
propertie to use in the g:each tag
<g:each in="${Navigation.findAll('from Navigation as n where n.css=?', ['ctBoven'])}" var="oNavigation" status="i">
This allows me to read any database from any page.
Recently, I'm trying to migrating my application from CakePHP to Grails. So far it's been a smooth sailing, everything I can do with CakePHP, I can do it with much less code in Grails. However, I have one question :
In CakePHP, there's an URL Prefix feature that enables you to give prefix to a certain action url, for example, if I have these actions in my controller :
PostController
admin_add
admin_edit
admin_delete
I can simply access it from the URL :
mysite/admin/post/add
mysite/admin/post/edit/1
mysite/admin/post/delete/2
instead of:
mysite/post/admin_add
mysite/post/admin_edit/1
mysite/post/admin_delete/2
Is there anyway to do this in Grails, or at least alternative of doing this?
Grails URL Mappings documentation doesn't help you in this particular case (amra, next time try it yourself and post an answer only if it's any help). Daniel's solution was close, but wouldn't work, because:
the action part must be in a closure when created dynamically
all named parameters excluding "controller", "action" and "id" are accessible via the params object
A solution could look like this:
"/admin/$controller/$adminAction?/$param?"{
action = { "admin_${params.adminAction}" }
}
The key is NOT to name the parameter as "action", because it seems to be directly mapped to an action and can not be overriden.
I also tried a dynamic solution with generic prefixes and it seems to work as well:
"/$prefix/$controller/$adminAction?/$param?"{
action = { "${params.prefix}_${params.adminAction}" }
}
I didn't test it, but try this:
"mysite/$prefix/$controller/$method/$id?"{
action = "${prefix}_${method}"
}
It constructs the action name from the prefix and the method.
Just take a look on grails URL Mappings documentation part
I'm developing a Grails web application (mainly as a learning exercise). I have previously written some standard Grails apps, but in this case I wanted to try creating a controller that would intercept all requests (including static html) of the form:
test 1
test 2
test 3
test 4
The intent is to do some simple business logic (auditing) each time a user clicks a link. I know I could do this using a Filter (or a range of other methods), however I thought this should work too and wanted to do this using a Grails framework.
I set up the Grail UrlMappings.groovy file to map all URLs of that form (/$myPathParam?) to a single controller:
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?"{
constraints {
}
}
"/$path?" (controller: 'auditRecord', action: 'showPage')
"500"(view:'/error')
}
}
In that controller (in the appropriate "showPage" action) I've been printing out the path information, for example:
def showPage = {
println "params.path = " + params.path
...
render(view: resultingView)
}
The results of the println in the showPage action for each of my four links are
testJsp.jsp
testGsp.gsp
testHtm.htm
testHtml
Why is the last one "testHtml", not "testHtml.html"?
In a previous (Stack Overflow query) Olexandr encountered this issue and was advised to simply concatenate the value of request.format - which, indeed, does return "html". However request.format also returns "html" for all four links.
I'm interested in gaining an understanding of what Grails is doing and why. Is there some way to configure Grails so the params.path variable in the controller shows "testHtml.html" rather than stripping off the "html" extension? It doesn't seem to remove the extension for any other file type (including .htm). Is there a good reason it's doing this? I know that it is a bit unusual to use a controller for static html, but still would like to understand what's going on.
This is related to content negotiation, which you can read about in section 6.8 of the Grails user guide. If Grails recognises the extension as a particular type, the extension is removed from the URL and the type is added to the "format" parameter.
You can disable this behaviour by adding this entry to grails-app/conf/Config.groovy:
grails.mime.file.extensions = false