I'm trying to render a view, defined in a module, in the main site homepage (~/) as it's main content. If the user is not authenticated, i need to show a login/register view instead.
The logged-in view lives in one module (Product Module) and the login/register view lives in another (Account Module). The logged-in view requires a service call to fetch data based on the user's products. I'm currently using standard mvc to render these views and fetch the data they require in their controllers.
Can this be accomplished by treating these views as shape templates? If so, are there any examples of pulling in views to the homepage like this? Or is there a better way of achieving this?
I have tried implmenting IHomePageProvider to return my own homepage ViewResult within the Product module, but without any success.
Cheers.
First, you might want to look into widgets and layers. You could define a layer for authenticaed users, and one for anonymous users, and attach widgets to those layers to achieve what you want. That might be the best way for you to accomplish this. Look in the Orchard docs for examples on how to do this.
I have done a similar thing before using custom controller and a lot of custom logic. Because of my specific requirements widgets and layers would not work for this. All the content on the page needed to change depending on some inputs, and widgets and layers were not going to be well suited for this. What I did was create a custom controller, and a corresponding Route with a high priority (so the Route takes precedence over any others that want to be the home page). I didn't mess with IHomePageProvider at all.
In the controller action I pulled the data necessary, and created the shapes I wanted, and then returned a result like this: return new ShapeResult(this, homePageShape);
homePageShape is constructed like this, right before the return statement:
// Create personalized home page shape:
var homeShape = _orchardServices.New.CustomHome(
SomeShape1: someShape1
, SomeShape2: someShape2
, SomeModel1: someModel1
...
);
This creates a shape called CustomHome, and orchard will automatically look for a template called CustomHome.cshtml in the views folder of your module.
I created several shapes (all the "someShapeX" vars you see above). Mostly they are created from content parts via the BuildDisplay() method. The content parts are queried using IContentManager, and the shapes are created like this (this example is for a slide show shape):
dynamic sliderShape = _contentManager.BuildDisplay(sliderPart, "Detail");
You can put logic in the controller to build the shapes you want depending on whether or not the user is logged in. In CustomHome.cshtml you would render a shape like this:
#Display(Model.SomeShape1)
Related
I'd like to use Nightwatch's Page Objects system for UI components used across our app. Because nightwatch has their own way of reading/initializing them, I don't see a way of properly extending/re-using them.
For example I want an DateInputPageObject for "date fields". It would identify the label, input, date picker, etc.
I'd use it on any page with a date input field.
I would also like to extend page objects. For example, class FooModal extends Modal. The ModalPageObject would define selectors for elements all modals have - the overlay, container, close button, etc.
I can't find any way to do this in nightwatch, is it possible at all?
The problem is not with nightwatch per se as it's just following the basic structure of page object model BUT that is a very good question and it brings out one of the drawbacks of page object model.
Page object model has been around for some time and the problem with that is that it doesn't serve the needs of modern web applications that use component libraries & living style-guides and re-using components.
Personally I found it easier to use a global json file with all the components structured based on their type. e.g. labels, fields, buttons, etc.
I'm writing a custom Orchard module with a custom Theme. I would like to pass data from the View back to the Layout to change the layout based on data determined in the View.
In my example, I have a left-nav in my theme - certain views should be able to instruct the layout not to render this left-nav.
In standard mvc 3 I would just pass the value up through the ViewBag, but this doesn't seem to be working within Orchard - I'm guessing that the layout code is executed before the View is rendered?
I've looked into using a Shape to move this data around but looks like it might be a little heavyweight for what i'm trying to achieve.
What's the best practice for passing data around like this as an alternative to ViewBag?
Update: After playing around with it a bit more i've just noticed that TempData is being picked up in the Layout - can anyone explain why TempData is transmitted, but ViewData isn't? And is it safe to use from an Orchard POV?
It's easier than that... All templates have access to the Layout shape, which is a dynamic object. This means that you can modify it on the fly, add it properties, etc.
In your specific case, suppressing a zone, you may even be able to just set that to null: zones are just shapes, and in the case of top-level zones they are expandos on Layout. So if you have a zone named Foo, setting Layout.Foo to null should do the trick. As a matter of facts, I'm doing exactly that in one of my themes, to suppress the side bars from my error pages without having to create a specific widget layer:
Layout.AsideFirst = null;
Layout.AsideSecond = null;
Im using joomla MVC and I want to build a form that has different tabs which are different sections of the form with inputs in it. There are some tabs that are common to other forms that I need to include.
I would like to be able to load this common content from a separate file or view so i dont have duplicate code, plus is easier when I need to do a change to the form so I dont have to do it in all the forms. It's like displaying a view inside another view.
Is there a way to accomplish this?
A Joomla! provides the loadTemplate method to views.
So if you're currently in a tmpl file loaded for layout edit (ie. tmpl/edit.php ) you can call $this->loadTemplate('tab1'); and Joomla! will load the tmpl/edit_tab1.php file in the same view as your edit.php.
In that same view if you wanted to include say tmpl/other_tab1.php you would have to temporarily set the layout to other, eg. in one of our components during the Run template we need a tab from the Edit template, so we use:
<?php $this->setLayout('edit'); // This is ugly
echo $this->loadTemplate('plan');
$this->setLayout('run'); ?>
To load a template from another view alltogether, I think you would have to temporarily over-ride the view value, load the template then restore the view. eg.
$jinput = JFactory::getApplication()->input;
$jinput->set('view', 'other');
$this->loadTemplate('tab2');
$jinput->set('view', 'original');
NB: this last bit I haven't had time to test but it should work.
You can load a different template file for a different view manually, by simply requiring it. The following is for a view called "nameofotherview" with the layout "layoutname". If this is for an admin view use JPATH_COMPONENT_ADMINSTRATOR instead.
require(JPATH_COMPONENT_SITE . '/views/nameofotherview/tmpl/layoutname.php');
Remember that the data set up in the view class needs to be compatible with the main layout as well as the layout you're loading from elsewhere.
A side effect of doing this is that template overrides won't work. The loadTemplate function is doing a require but it checks the template paths for overrides first.
You can use vews in other views as described in Joomla documentation: Sharing layouts across views or extensions with JLayout
I am writing a helper class to query my Zenfolio feed, return and display the images. Right now this code is split between a viewmodel and code in my controller. I want to pack it up into a helper class. Would all the code go into the helper or do i still split the code among different class with the helper only responible for generating the html? I have googled but not found an answer to my question.
Within the MVC pattern there is a clear separation between Model (data), View (html) and Controller (what gives the Model to the View).
To answer your question, No. Load your models in your Controller. Display them in your View. Html Helpers should only generate html for your view.
You may want to consider using a DisplayTemplate, which allows you use the same View template for every model of a particular type.
I wouldn't do any data access from the view. This sounds like a good use case for an action, and reusing code via the RenderAction method. You can mark the action as a child action using the [ChildActionOnly] attribute, which ensures it can't be invoked directly from the HTTP request, and return a PartialView result.
HTML helpers should really be used to generate HTML tags from data taken from the ViewData or Model (i.e. your view model in this case).
Data access in an HtmlHelper is only pain.
I've had the misfortune to inherit a project that had ad-hoc SQL placed into the HtmlHelpers by the 2nd developer on a project. The HtmlHelpers were beautifully written by the first developer, and the ad-hoc SQL pretty much nullified all of the time and effort put into having an service oriented architecture, having an ORM (the 2nd level cache became worthless), the unit of work pattern(transactions, worthless), and every aspect of design. Eventually, this 2nd developer had to make larger and larger HtmlHelpers so that different elements could share access to the data.
This was originally done for a display mode, and editing was accomplished through a pile of ugly custom javascript. All told, when the page rendered, it made 600 synchronous calls to the database.
CodeIgniter + Template howto design a portal like behavior.
I'm not getting the concept of how to design bigger sites with CodeIgniter and Templates.
The templates I'm using is Template Library for CodeIgniter. I'm having problems solving the following.
What I can see I need is some MasterTemplate that provides "MainRegion" for ProductCatalogue browsing and Account management etc. Then I would like to have a concept of "Widgets" loaded from the MasterTemplate that the user does not interact directly with instead it is simply informative. Ex: ShoppingCartWidget, TopNews etc...
Example of problems:
A) Widget - A shopping cart widget exposes a minimalistic resume of what user has added when browsing the the product catalog in the "MainRegion".
B) Hierachival view structure - When navigating to the "Account section" of the site the site renders a sub-view of the account system in the "MainRegion". My problem is that the state of the AccountSection is lost when I for example leave the "AccountSection" in to "ProductCatalogue" and the back to "Accountsection". I want to be able to render each subsection independtly smothly insterted into the "MainRegion" in the master template.
I really don't get the architecture. I need help to bring real modularity into the design.
I would like to achive the following:
1) View fragments should render from a its own model. Ex: ShoppingCartWidget always reads its state from ShoppingCartModel.
3) View fragments should have a display[on/off] in some MasterTemplate concept. So that I can Ex: Start showing the ShoppingCartWidget when there is something in the ShoppingCart. (I don't want to render '').
4) Stateful views. Ex: UserLoggedIn/UserNotLoggedIn
I'm missing the complex design principles for bigger sites or best practices for CI.
Very greatful for any help!
Thanks
Niclas
HMVC for Codeigniter does what you want: https://bitbucket.org/wiredesignz/codeigniter-modular-extensions-hmvc/wiki/Home