I am new to orchard i had made a simple module using MVC and Entity Frame work ..The module is simple Crud application.I had integerated this module on my orchard site and this module works fine on front end.But i had problem how to configure same module on admin panel in orchard i want to do these functionalities on admin site
Create a controller called AdminController or decorate a controller with the [Admin] attribute (using Orchard.UI.Admin).
Then to create a menu item create a file called AdminMenu.cs in the route of your project with the following code:
using Orchard.Localization;
using Orchard.UI.Navigation;
namespace MyFirstModule {
public class AdminMenu : INavigationProvider {
public Localizer T { get; set; }
public string MenuName { get { return "admin"; } }
public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("My admin menu item"), "50",
menu => menu.Add(T("My admin menu item"), "20", item => item.Action("Index", "Admin", new { area = "MyFirstModule" })
.Permission(Permissions.ConfigureRobotsTextFile)));
}
}
}
This will add a menu item that links to your action. Then you can do whatever admin stuff you want :)
Related
I've tried to scaffold dynamically some domains in GRAILS , but after adding items into database they doesn't show up in the listing view (User/index) in this case :
User.groovy
package scaffold_test
class User {
String username
String address
static constraints = {
}
}
UserController.groovy
package scaffold_test
class UserController {
def scaffold=true
def index() { }
}
so after running the application, I can see the User controller in the Grails home page,I can add Users, and I can see the added instances via DbConsole. But i can't list the instances in the User/index view. Thanks !
Delete def index() { } to let the scaffolding generate all of the methods.
I've been able to find several examples on role based authentication, but this isn't an authentication issue. I have three user types, one of which I want to have a different default starting page. Route-config is initialized before the the user information is available.
In a nut shell: If Role A or Role B start below
Controller: Home
Action: Index
else:
Controller: Other
Action: OtherIndex
Where and how should this be implemented?
EDIT
This should only occur the first time the site is accessed, the other users can go to Home/Index, just not by default.
EDIT
Using Brad's Suggestion I created a redirect attribute with his redirection logic, and applied it to Index. I then created another action for the page. This way if I do need to allow access to the HomeIndex I can specifically assign it with Home/HomeIndex, and anything that uses the default routing can hit the Home/Index
[RedirectUserFilter]
public ActionResult Index()
{
return HomeIndex();
}
For those who need it - here is the Attribute
public class RedirectUserFilterAttribute: ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext actionContext)
{
if (!HttpContext.Current.User.IsInRole("Role A")
&& !HttpContext.Current.User.IsInRole("Role B"))
{
actionContext.Result = new RedirectToRouteResult(
new RouteValueDictionary {
{ "Controller", "OtherController" },
{ "Action", "OtherAction" } });
}
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
if (
!User.IsInRole("Something") &&
!User.IsInRole("Role B")
) return RedirectToAction("OtherIndex");
// ...
}
}
Same goes for OtherController.
Alternatively you could create your own ActionFilter that looks for a conventionally-named action (like IndexRolename over Index)
I have an almost standalone Orchard module. It is an app comprising a collection of controllers and views, and in performs it's own EF based data access.
Once I have installed and activated this module in Orchard, how do I request it's controller actions and be served it's views in response? I understand it must have a Routes class and suspect it is something here that I must do to enable access to my module. I know a module is actually an Area, but I still battle to understand the Routes class.
Let's say my module has one controller, action and view, Home, Index, and Index, being Home/Index. Once Orchard is up and running, how do I access this specific Index actin?
There is a good guide in the Orchard Documentation to Creating an Orchard Module that uses its own controllers.
Here is a code sample taken from that guide that creates the routes for a module called HelloWorld:
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.Mvc.Routes;
namespace HelloWorld {
public class Routes : IRouteProvider {
public void GetRoutes(ICollection<RouteDescriptor> routes) {
foreach (var routeDescriptor in GetRoutes())
routes.Add(routeDescriptor);
}
public IEnumerable<RouteDescriptor> GetRoutes() {
return new[] {
new RouteDescriptor {
Priority = 5,
Route = new Route(
"HelloWorld",
new RouteValueDictionary {
{"area", "HelloWorld"},
{"controller", "Home"},
{"action", "Index"}
},
new RouteValueDictionary(),
new RouteValueDictionary {
{"area", "HelloWorld"}
},
new MvcRouteHandler())
}
};
}
}
}
If you create a class that implements IRouteProvider you can let Orchard know the routes for your controllers.
I am new to mvc 3 and I'm using it with the asp.net membership provider....so I'd like to create an extension method to let me get the logged user GUID from any controller whitin my website
Something like that:
public static Guid GetLoggedUser(this Controller controller)
{
return (Guid)Membership.GetUser(controller.User.Identity.Name).ProviderUserKey.ToString();
}
Any ideas?
Why not use "User" property already on the ControllerBase class?
public class MyController : Controller
{
public ActionResult GetUser()
{
var userName = User.Identity.Name;
}
}
You can include additional information about your user by using a custom IPrincipal/IIdentity. Here's how it is done if using Forms Auth.
I have a list of blog post categories(~20) in a look up table.
I want to display them on multiple pages as list of hyperlinks that user can click.
I also want to display them in a dropdown list in 2 or more places(different view pages)
The follow works & I see categories as a menu/list of hyperlinks.
But this will cause me modify multiple controller where I need to show the categories.
What is the best practice to handle this so that I have minimal code change?
//#1 I added new class in one of my model:
namespace MyApp.Models
{
...
public class ShowPostModel
{
public Post Post { get; set; }
public IEnumerable<Category> Categories { get; set; }
}
public class Category
{
public string _id { get; set; }
public string Name { get; set; }
}
}
//#2 Populating the controller
namespace MyApp.Controllers
{
public class BlogController : Controller
{
public ActionResult ShowPost()
{
ShowPostModel viewModel = new ShowPostModel();
viewModel.Post = ReadBlogPostFromDB();
viewModel.Categories = ReadCategoriesFromDB();
return View(viewModel);
}
}
}
//#3 This is from my main view for showing the Post:
#Html.Partial("_Categories", Model.Categories)
//#4 This is my _Categories partial view:
#model IEnumerable<MyApp.Models.Category>
<section>
<header><b>Categories</b></header>
<ul style="padding:0;margin:0;">
#foreach (var cat in Model)
{
<li>
#cat.Name
</li>
}
</ul>
</section>
Thanks for reading
Edit:
I made these changes and it seems working as well.
Any comments or improvements I can make here?
//#1 deleted this line from public class ShowPostModel (model is now DRY)
public IEnumerable<Category> Categories { get; set; }//deleted
//#2 created a base controller and inherit from it
public abstract class BlogBaseController : Controller
{
public BlogBaseController()
{
ViewBag.Categories = ReadCategoriesFromDB();
}
}
//#3 force all controller where I need categories to inherit from base controller
public class BlogController : BlogBaseController
//#4 change how I read in my views
#Html.Partial("_Categories", (IEnumerable<MyApp.Models.Category>)#ViewBag.Categories)
If you use the categories in enough places, you can encapsulate this into a base controller class, and override OnActionExecuted.
I would then put the Categories into a property on the ViewBag and pass it into your partial view from there, and leave your view's model alone.
i wonder why no one has suggested using RenderAction. you can write this Action method in you base controller. this will make it available in all derived controller. this way you can have your categories view strongly typed. Moreover, you should put your Categeories view in Views/Shared directory so every controller has access to this view. Doing so will keep you DRY and you still have the benefits of having strongly typed view.
EDIT By the way you don't have to have base controller to use renderaction. Although above approach is valid and i prefer doing like this but you can also have a nvaigation controller like
Public NavigationController:Controller()
{
public ActionResult Categories()
{
var Categories = FetchFromDB();
return View(Categoires);
}
}
Now you can call this action method using renderAction on anywhere in your application
You might want to try creating 2 display for templates, one to display in link and one to display in dropdown. Depending on the page you tell the view to use the specific template.
You can create a Filter that populates your categories and adds it to ViewData/ViewBag. You can then apply this filter to the controllers/actions that require the categories.
For displaying, you can use EditorTemplates or Partials to keep your UI code DRY...
HTH.