How to add breadcrumb to Spring MVC? - spring

How can I add breadcrumb to all pages of Spring MVC? I suppose it would be a good question to ask as breadcrumbs are quite popular now and it might be the question of many others.
I've found this solution that is using dummiesmind.breadcrumb.springmvc.annotations, there is also a question on stackoverflow but I could not learn much except finding similar solution to the one that Ive found. Another solution is this one that is using JavaScript.
Does anyone have a better option to the ones I mentioned?
#Link(label="Sample Link", family="controllerFamily", parent="");
#RequestMapping(value = "sample.do", method=RequestMethod.GET);
public ModelAndView sampleMethod(HttpSession session){...}

What are you using to display your pages ? JSP ? Thymeleaf ?
The link you point to seems a good option or at least you can build something custom that works for you based on that. Using annotations keeps your code clean but you need to make sure you add them everywhere.
You could use an abstract controller where you define a method to create a ModelAndView object for all pages. You could add breadcrumbs that way :
protected ModelAndView createModelAndView(String pageName, BreadCrumb breadCrumb) {
ModelAndView modelAndView = new ModelAndView(pageName);
modelAndView.addObject("breadCrumb", breadCrumb);
return modelAndView;
}
Of course you would need to call that method everytime in your implementation.
One usage of this would be to pass your request url as parameter and parse it to build breadcrumbs by associating text to each part of the path (using the current local to tanslate it). So for example "/admin/user/list" would give you Home >> Administration >> User management >> List of users. That should be easy to build.

Related

How to handle AJAX calls after globalizating an MVC5 Website?

Background
I've inherited an e-commerce website using the usual aspnet's MVC5 / razor / jquery. The goal is gobalizating the website and add a language selector, to support the two main country/language targeting strategies. I've just accomplished the first step, wich is routing the website so it handles domain.com/en/, domain.com/es/, domain.com/es-mx/... Using http://jittuu.com/2014/3/17/AspNet-localization-routing After this, entering the domain with a non-existant locale redirects to the default one. There's a custom IRouteHandler that get's the httprequest, checks the locale and puts it if it needs to:
Public Class LocalizationRedirectRouteHandler
Implements IRouteHandler
Public Function GetHttpHandler(requestContext As RequestContext) As IHttpHandler Implements IRouteHandler.GetHttpHandler
Dim routeValues = requestContext.RouteData.Values
Dim cookieLocale = requestContext.HttpContext.Request.Cookies("locale")
If cookieLocale IsNot Nothing Then
routeValues("culture") = cookieLocale.Value
Return New RedirectHandler(New UrlHelper(requestContext).RouteUrl(routeValues))
End If
Dim uiCulture = CultureInfo.CurrentUICulture
routeValues("culture") = uiCulture.Name
Return New RedirectHandler(New UrlHelper(requestContext).RouteUrl(routeValues))
End Function
End Class
There are thousands of "inline" AJAX calls to routes across the website written without an #Html helper because the project has separate, bundled js files, failing. There are hundreds of routes failing because the project controllers are using attribute routing and it's not specifying locale. For example, a simple link to a product features is failing because the controller has a route specifying
/product/{id}
but the URL looks like
/es-MX/product/{id}
Question:
What's the right way to proceed here?
I was expecting those AJAX and links without locale to be redirected, but they are not.
Should I rewrite all those files so they specify current locale? Is there any other "healthy" way to do this, like extending BaseController and add culture as a route prefix?
Thank you in advance for your time, I'm terribly lost here.
Turns out, this answer by #NightOwl888 is the closest I've found to a solution to the problem I was facing. After including this changes to my project, I have almost everything working out and sporting a wonderful culture prefix on the URL. There's still a few things to work out though:
My default route sports no culture in the URL, wich may be against one of our goals. I can work on that toying (or removing) the defaultCulture constraint.
There are hundreds of windows.location on js files targeting routes without culture. I may be able to work on that via JS global variable storing the culture.
I still need to find a nice way to handle URL localization. Hopefully this project will help me through (also directed there by #NightOwl888).

Accessing dynamic links in the format of domain.com/<dynamic_page_name> in CodeIgniter

I am using code Igniter for my PHP project. I want to give provision in my site such that users can create new pages of their own, and access them directly from domain.com/their_page_name.
But, my developers have raised a concern that, 1000's of dynamic links that are presented in the format of domain.com/ is "not good for site's performance". For some 10-15 pages, it is fine. But, beyond that, it would effect the site's performance.
So, they proposed that the URL format should be like www.domain.com/something/page_name (here, 'something' is the controller name, as they mentioned it)
But, I really can't sacrifice my framework nor my requirement.
Is there any way that I can achieve the format of "www.domain.com/page_name" without effecting the site's performance?
Thanks in advance.
No issues on
Www.domain.com\userpagename.
It's not a framework issues. Codeigniter support this type of URL.you can create n no of URL.
Performance will matter how you are handling that particular controller or that particular function.
If may be 10 may be 100 ,work around same way.
You just have to put route accordingly.
$route[default_controller]=userurl;
$route[userurl/(:any)]=userurl yourfunction/$1`;
What it seems you need is dynamic controller, which can be done using Codeigniter's build in function _remap().
A code example is:
public function _remap($method){
if($method != null){
$this->yourFunction($method);
} else {
// handle the error as you like
}
}
public function yourFunction($key){
// your code logic here
}
All this code block goes inside your controller.
Edit: the performance is exactlu the same as going with domain.com/controller/method. What it matters, as stated above, is how you handle the data.

ApiController within an area

I want to have BlaController : ApiController, with BlaController located in /Areas/XXX/ ( or namespace MySolution.Areas.XXX.Controllers )
The problem is that when I browse to http://localhost:1935/XXX/Bla/SomeAction I get 404.
Normal controllers (: Controller) do not throw 404.
Note: SomeAction would be for example "public string SomeAction() { return "hi"; }", within BlaController
*Note 2: Tried* http://localhost:1935/api/Bla/SomeAction and didn't work either
Based on this SO question, looks like you need to build your own HttpControllerFactory in order to support Areas with WebAPI.
The question references an article on how to do this: http://netmvc.blogspot.com/2012/03/aspnet-mvc-4-webapi-support-areas-in.html
Hope this helps.
UPDATE:
Thanks to Bertrand who pointed to an updated article about WebApi support for Areas (which is still doesn't have by default). The updated link is http://netmvc.blogspot.be/2012/06/aspnet-mvc-4-webapi-support-areas-in.html

Routing document-relative static urls in MVC3

I'm integrating a JavaScript library into an ASP.NET MVC3 web app. The library assumes it will be installed next to the page that references it, and so it uses document-relative URLs to find its components.
For example, the default directory layout looks like
container-page.html
jslibrary/
library.js
images/
icon.png
extensions/
extension.js
extension-icon.png
However, I want to reference the library from the view in /Home/edit. I install the library in the default Scripts\jslibrary\ When I reference the library in the view in Views\Home\edit.cshtml, the library's document-relative links like
images/icon.png
end up as requests to
http://localhost/Home/images/icon.png
which results in a File Not Found (404) error. How do I construct a route to look for
{anyControllerName}/images/{anyRemainingPathInfo}
and serve up
http://localhost/Scripts/jslibrary/images/{anyRemainingPathInfo}
?
(full disclosure: I'm still on IIS 6 in Production, and not much chance of going to IIS7 any time soon, so if this is better done at the IIS level, please account for IIS6. Thanks!)
You could create a controller for handling you redirect logic - for example an "Images"controller. Register a global route in your Global.asax file, using the pattern (more on this type of pattern here:
routes.MapRoute(
"Images", // Route name
"{xyz}/{controller}/{path}", // URL with parameters
new {controller = "Images", action = "Index", path= UrlParameter.Optional} // Parameter defaults);
In your controller:
public ActionResult Index(string path)
{
//format path, parse request segments, or do other work needed to Id file to return...
return base.File(path, "image/jpeg"); //once you have the path pointing to the right place...
}
Not sure if this solution will work for you, wish I could come up with something more elegant. Best of Luck!
Short of rewriting the library and having it check for the appropriate directory the only solution I can think of is to include the views, library and supporting files in a directory structure that the library can access. This of course would break MVC's convention over configuration way of finding views, so you would have to write a custom override of the way Razor looks for views, which is not too complex to do, but you might be making life more difficult for yourself down the road depending on your application. Your call which is the lesser of the two evils :) (I'd go for fixing the library)
Make a help function
#functions{
public string AbsoluteUrl(string relativeContentPath)
{
Uri contextUri = HttpContext.Current.Request.Url;
var baseUri = string.Format("{0}://{1}{2}", contextUri.Scheme,
contextUri.Host, contextUri.Port == 80 ? string.Empty : ":" + contextUri.Port);
return string.Format("{0}{1}", baseUri, VirtualPathUtility.ToAbsolute(relativeContentPath));
}
}
Calling
#AbsoluteUrl("~/Images/myImage.jpg") <!-- gives the full path like: http://localhost:54334/Images/myImage.jpg -->
This example are from
https://dejanvasic.wordpress.com/2013/03/26/generating-full-content-url-in-mvc/

MVC3 Url.Action() - Is there a simpiler way to write links in MVC3?

I'm working on a site and I'm new to MVC3 Framework. I'm coming from a place where writing URL's is very simple href="some/web/page.html" but now with the MVC3 URLs are more complex.
By complex I mean are more involved to write. href="#Url.Action("index", "Home")" that requires hitting the shift key multiple times which is tiresome and redundant for someone coming from href="some/web/page.html" only hitting shift twice for that.
And the site I'm working on is using areas which adds another level of complexity to the URL.
href="#Url.Action("index", "area", new { area = "some_area})"
I'm working on a 100+ page site. Writing these #Action.Url() is becoming boring and irritating. Is there something I can do to cut out the redundancy?
You could try using T4MVC, other than that there isn't really much you can do.
You can read it's documentation here.
You can make some extension methods like Kazi explains here :
http://weblogs.asp.net/rashid/archive/2009/04/01/asp-net-mvc-best-practices-part-1.aspx
Something like this :
public static class UrlHelperExtension
{
public static string Home(this UrlHelper helper)
{
return helper.Content("~/");
}
}
You can also use David Ebbo MVC T4 template for generating helper methods :
http://blogs.msdn.com/b/davidebb/archive/2009/06/01/a-buildprovider-to-simplify-your-asp-net-mvc-action-links.aspx
http://blogs.msdn.com/b/davidebb/archive/2009/06/26/the-mvc-t4-template-is-now-up-on-codeplex-and-it-does-change-your-code-a-bit.aspx
http://mvccontrib.codeplex.com/wikipage?title=T4MVC_doc&referringTitle=T4MVC
Hope this helps

Resources