In Orchard how do I render the editor for a ContentType on a cshtml page inside my module - handler

I have a contentType defined, along with a driver + handler, it works fine inside of the admin page but I want to render the editor for a contentType on a cshtml page inside my module. How do I do this and can I still get the benefit of the parts being persisted etc.

You can use IContentManager.BuildEditor(...) to produce the editor shape for a content item, and render it in your view using #Display(Model.Whatever).
To deal with updates, you can also use IContentManager.UpdateEditor(...), passing in an implementor of IUpdateModel.
IUpdateModel is just an Orchardy way of abstracting calls to TryUpdateModel and AddModelError that you find in regular ASP MVC controllers, so if you are rendering your editor from a custom controller you can implement it easily like this:
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {
return TryUpdateModel(model, prefix, includeProperties, excludeProperties);
}
void IUpdateModel.AddModelError(string key, LocalizedString errorMessage) {
ModelState.AddModelError(key, errorMessage.ToString());
}
You can find a nice succinct example in Orchard.Blogs.Controllers.BlogAdminController.
As an aside, you might recognise IUpdateModel and prefix from developing your content part driver - this abstraction is extremely versatile as it allows you to deal with multiple editors being updated at the same time (this is how stuff like content parts, fields etc have been implemented). It allows you to do some cool stuff like edit multiple content items on the same page. We use this at my work to implement a custom forms editor which has some nice features like drag and drop design etc.

Related

Best Practice to display text label on a .NetCore Razor page

Is it best practice for ALL text on a .Net Core Razor webpage to be injected with Model Binding (Even on a static page), or should I only inject text which may need to change dynamically at runtime?
E.g. My Index.cshtml page has a h1 title as per below. Is this considered bad practice or is it ok?
<h1 class="block-title-text" localize-content>A Fun Title</h1>
Thanks. Just trying to get my head around Razor and .Net Core.
This if fine, in general you should keep user interface elements in the view (or the .cshtml file for Razor Pages). See benefits of using views for more details, which among other things includes:
The parts of the app are loosely coupled. You can build and update the app's views separately from the business logic and data access components. You can modify the views of the app without necessarily having to update other parts of the app.
Just realised something which is obvious in hindsight. By injecting the strings using Model Binding instead of placing them into the HTML as above, it allows the incorporation of unit tests around those strings.

Accessing controls in Razor view from controller MVC4

I am new to MVC. In my application the view page created using razor by designing it from another html page designer. I have doubt that how to access the html controls from the corresponding controller. For example, i create a controller named Home and and corresponding view. Added a text box into it.
<input id="name" type="text" name="txtName"/>
Now i want to get and set the value in text box from controller without using script.
Just like
txtName.text="...."
Is that possible..?
It sounds like you are thinking of things from a Web Forms perspective, e.g. controls, setting properties server-side.
MVC allows much better separation of concerns, that is, each piece should play its part without being tightly coupled to other parts. Having a controller set a property of a textbox in a view means that there must always be a textbox in that view and would tightly couple the controller to that particular view. It is not directly possible and it would be a bad idea even if it was.
That's where view models come in:
// M - model
public sealed class MyViewModel
{
public string Name { get; set; }
}
// V - view
#model MyViewModel
// (usually code to begin a form goes here)
#Html.TextBoxFor( o => o.Name )
// C - controller
public ActionResult MyActionMethod()
{
var model = new MyViewModel { Name = "Hello" };
return View( model );
}
It may seem like an extra step (it is) but it is cleaner, far more flexible, and far more test-friendly.
It would only be possible with another request to the server (e.g. POST, GET) because the Controller code can only run server-side. After processing another request, you could use a ViewModel to populate your HTML text-box while rendering it, but I doubt that is what you are looking for.
If you are familiar with desktop programming (e.g. Window's Forms) and you are looking to immediately change and process fields on an HTML page, you will need to use JavaScript. If you are unfamiliar with web-programming, or even just new to the MVC paradigm, I suggest you try out a few MSDN tutorials.

ASP.NET MVC Set texts in the View or in the Controller

What is the best practice in MVC (for testing, SOC and scaffolding) for setting texts (for exemple page title, h1,h2..)
Is it better to do it in the controlle, fill a viewmodel and send it to the view
or directly typing texts in the view?
Also I will propably use ressouces files for global texts (like button text, menu texts) and local ressouces for view specific texts.
The view is merely to present the output to the user. Depending on your requirement you can either:
1) Type the text in the view directly <h2>Hello World</h2> (for static content that will not change)
The latter two options are for ideal for dynamic content, where the content could be received from a database or some additional input.
2) Use the ViewBag to pass information to the view (in which case you would set it in the controller ie. ViewBag.HelloWorld = "Hello World" : <h2>#ViewBag.HelloWorld</h2>
3) Use a model to pass the information to your view. This should be your preferred option where possible. In your specific case you could use the controller to retrieve the content from your global resources, bind it to the model and pass it to the view.
The logic on where to get the data should come from the controller and the View's function should be to merely display it.
I recommend binding properties on the viewModel to the UI.
This is not only more testable, but it's also more flexible. It makes it easier to implement features like mult language support etc.
I recommend avoiding hard coding text in the markup if you can

What should I prefer to use widget or renderPartial in Yii's view?

I am confused when I should use a custom widget or renderPartial in my view files. Sometimes I use widget and sometimes I use renderPartial.
Widget
You use widget when your application logic is defined in a separate CLASS file and the logic is somehow separated and standalone.
Widget's are chosen when the functionality is repeatedly used elsewhere, on lot of pages.
renderPartial
You use renderPartial for VIEW files that you want to embed into something bigger, or when you want to print something without using the application layouts.
renderPartial is chosen when all the variables it need to access are already prepared in the current action.
Widget
You can use widget when your site has some common part like header and footer or sometime some kind filter which require on every page of site.
renderPartial
Take example of search form of yii crude which is called by using renderPartial because that serach form is changing according to requirement of pages.
Sorry for english.

Kohana 3: How to provide API functions in template/view like WordPress?

I'm working on a project which allows the advanced user to define their own way of showing the information and access some basic API. For example, I provide a show_search_box() function so that the user can call this function in the view file when they want to show the standard search box, or they could call the function with parameters to customize the search form.
e.g. this code in the template will show a search form with watermark text "Enter keyword here".
<div><?php show_search_box('Enter keyword here'); ?></div>
What I'm thinking actually is exactly like what WordPress does in its template tags. (http://codex.wordpress.org/Stepping_Into_Template_Tags)
My idea is to create a class that provide all those API functions and pass an object instance of the class to the view file, so users can call the API functions in view like:
<div><?php $API->show_search_box('Enter keyword here'); ?></div>
I think it will work, (but have not tested it yet), but I prefer providing a set of direct called functions just like WordPress. What's the best way to do this with kohana 3?
======Update: I have tested the method of pass $API object to view, and it works as expected.
class API {
public function show_search_box($watermark){....}
}
In the controller, pass the $API to the view/template
public function action_index()
{
$this->template->API = new API();
}
Then call the function inside view/template as described above.
Unlike those controller methods, $API cannot access the controller's variables unless they're explicitly assigned: e.g. $API->setVar('VarName', $a_controller_variable), which is quite tedious i think.
Well, unlike Kohana 2.3, views don't execute in the controller namespace, so you can't simply do $this->something().
If you have all your functions in one Model, let's call it API, then you could do this in the view (or base controller if you want it available everywhere)...
$this->template->internalView = View::factory('your_view')
->set('API', Model::factory('API));
(assuming you have a <?php echo $internalView; ?> in a parent view).
Then you could do in your view...
<div><?php $API->show_search_box('Enter keyword here'); ?></div>
Which will run your method on your model. Views shouldn't really know about the existence of models, but your case ma be an exception. Perhaps you could use a helper sort of class instead of a model, if you are worried about breaking the MVC paradigm.
If you want to do what WordPress does (have a bunch of global functions, which I don't recommend), then you will need to define them somewhere. Kohana doesn't really have an easy spot to place them, as it doesn't really cater for a bunch of global functions.