I am not able to send model parameters on layout file via controller action. How to do that?
Add a proprety to your controller
public $model;
In you controller action
$this->model = $model
From your layout you can access the model by
$this->context->model
You can also use model class in layout file. For eg
use app\models\Property; // Property is model name
and then in file
$prop = Property::findOne($id); // say $id id int > 0
You can this model (its properties and method) any way you want
Related
I have a custom field in Orchard, I want it to have its own admin view to set the fields default value so that when it is used with other parts - it will always use this default display value.
I have the part, and the admin menu, currently the admin menu goes to the fields settings controller, but how do I create the fields shape for display?
I imagine something like this, but can't figure out what is the correct way to create the fields editor shape:
[Admin]
public class FieldAdminController : Controller
{
public ActionResult TimezoneSettings()
{
// var timezoneShape = Shape.Create("?");
// var model = new TimezoneViewModel(timezoneShape);
// return View(model);
// Or:
// TimezonePart part = Services.ContentManager.New<ITimezoneField>("TimezoneField");
//var model = Services.ContentManager.BuildEditor(part);
// return View(model);
}
}
The field does already work (i.e. the driver is working) when you attach the field to a content part via the admin UI, but I will only be using it with other code created custom parts in my modules.
I'm trying to work with the grid.cshtml alternate in my theme and need to check if a certain class has been added to the grid through the layout editor, is there a way to either iterate or check against the classes that are assigned to the model?
You can access the classes through the model by doing this in Grid.cshtml (and probably all other elements):
#{
IEnumerable<string> classes = Model.Classes;
var hasMyClass = classes.Contains("myClass");
}
#if (hasMyClass) {
<h1>This Grid has css class 'myClass'!!</h1>
}
I have created a View using module, now in controller of this view i need to fetch some specific content type and return to view. Please can some one eleborate with code sample.
You will need to inject the IContentManager services in your controller constructor (see dependency injection) , but since you will need to populate a new shape, you could inject IOrchardServices which will include a few common OrchardServices in one instance.
IOrchardServices services;
public MyController(IOrchardServices services){
this.services = services;
}
Then in your action (if you want to show it on the front end you will have to mark it as themed), do something like this:
[Themed]
public ActionResult MyAction(){
//Notice that you can filter the contentItems here, this is just a basic example
var myContentItems = services.ContentManager.Query().ForType("MyContentItem").List();
//You probably need to create a new shape for showing the ContentTypes
var shape = services.New.YourCustomShape(); //Notice that you must create a view that matches this name
shape.YourContentItems = myContentItems;
return new ShapeResult(this, shape);
}
And that's it.
I'm looking for guidance how to have form prefilled with data taken from existing object. I guess it should be working with method setData, I was expecting something simple like
$form->setData($existingObject) but no success.
For better explanation let's have a simple example.
I have form where user inputs his personal data. Form is created in controller by calling form.factory,
$form = $this->get('form.factory')->create(new personType());
I have form class "personType" and this form class has defined data_class object called "person". User submits form, data are saved in object person and this object is saved in session. I need to have option reopen the form and fill in data saved in object stored in session.
In your controller, you need to create/find your object then pass it to your createForm
$task = new Task();
$task->setTask('Write a blog post');
$task->setDueDate(new \DateTime('tomorrow'));
$form = $this->createForm(new TaskType(), $task);
http://symfony.com/doc/master/book/forms.html#creating-form-classes
In your exemple, try
$person = ...;
$form = $this->get('form.factory')->create(new personType(), $person);
What is the best way to pass the model variables to layout in Grails? Specifically, I'm using Spring security plugin which has User class. I also have Contact class that looks like this:
class Contact {
String realname
String company
String mobile
String fix
String email
User user
...
What are the options for getting the currently logged in person's company in my layout (main.gsp)?
To add to the above answer, you could alternatively set a session variable for the user when you login in whatever controller method gets called.
You can also just set a session variable for the company in the controller method:
session.company = Contact.findByUser(session.user)?.company
or from the example above
session.company = Contact.findByUser(SecurityContextHolder.context.authentication?.principal)?.company
And in your main.gsp, something like:
<span id="companyName">${session.company}</span>
Do you mean that you need to pass this model for every page, automatically, instead of manual passing it at render at each of controllers? You can use filters there:
def filters = {
all(controller: '*', action: '*') {
before = {
request.setAttribute('loggedInPerson', SecurityContextHolder.context.authentication?.principal)
//Notice, that there is used original Authentication, from Spring Security
//If you need you can load your Contact object there, or something
}
after = {
}
afterView = {
}
}
}
and use loggedInPerson at your gsp:
Hello ${loggedInPerson.username}!
Btw, there is also Spring Security tags, that can help you without using your own filter, like:
Hello <sec:loggedInUserInfo field="username"/>!
If you want to add a certain object to the model, you can also use the "interceptors" provided by grails. To add a certain variable to a particular controller, you can use something like this.
def afterInterceptor = {model, modelAndView->
model.loggedInUser = getLoggedInUser() // retrieve your user details here
}
And you can retrieve loggedInUser in the main.gsp layout as ${loggedInUser}.
If you need to get these details in multiple controllers, you can create a BaseController and keep the afterInterceptor in this BaseController. All controllers which need the reference to the logged in user in their corresponding views should extend the BaseController.