we are trying to build a more loosely coupled composite based web application, and looking at various options and frameworks.
The idea is like when the user browse to a page, the uri will be resolved on the server for a resource and a list of actions to take based on the configuration.
The view will be composed by some html markups and some components that are based on other URIs for their contents. The components are reusable and should not have any ideas about each other (maybe the context).
this is just an idea, and wanna see how the OpenRasta framework would help on this. I might be completely wrong with the approach; maybe this can be easily done with current asp.net webform and mvc framework, but i would like to see your opinion.
I have just completed an OpenRasta site that relies on standard webcontrols that I inject into my views, passing on the strongly typed Resource (supplied by OR via the handler) to enable the control to surface resource properties etc in the usual way.
The resource instance carries the path to the control to be loaded and injected (Resource.ControlPath). This is set in the handler by concatenating aspects of the URI to find the control. This allows different URIs to request different versions of the same control that live at different locations in the site file hierarchy.
So, for example, ClientA requires an intro view with lots of client-specific text and features. ClientB also requires an intro page with different content and features.
This give two URIs
/myapp/clienta/intro
/myapp/clientb/intro
Configuration
ResourceSpace.Has.ResourcesOfType<IntroResource>()
.AtUri("/myapp/{client}/intro")
.HandledBy<IntroHandler>()
.RenderedByAspx("~/Views/IntroView.aspx");
IntroHandler.cs
public class IntroHandler
{
public OperationResult Get(string client)
{
var controlPath = ClientService.GetIntroControlPath(client);
if (controlPath.IsEmpty()) return new OperationResult.NotFound();
return new OperationResult.OK{
ResponseResource = new IntroResource{
ControlPath = controlPath,
Client=client
}
};
}
}
}
Intro.aspx
<%# Page Language="C#" Inherits="OpenRasta.Codecs.WebForms.ResourceView<xx.IntroResource>" MasterPageFile="~/Views/View.Master" %>
<asp:Content ContentPlaceHolderID="head" ID="head" runat="server">
<link href="/assets/CSS/intro.css" rel="stylesheet" type="text/css" />
<%
var userControl = Page.LoadControl(Resource.ControlPath) as UserControl;
if (userControl == null) return;
var property = userControl.GetType().GetProperty("Resource");
if (property == null) return;
property.SetValue(userControl, Resource, null);
IntroContentControlHolder.Controls.Add(userControl);
%>
</asp:Content>
<asp:Content ContentPlaceHolderID="body" ID="content" runat="server">
<asp:placeholder runat="server" id="IntroContentControlHolder"></asp:placeholder>
</asp:Content>
Intro.ascx
<%# Control CodeBehind="intro.ascx.cs" Language="C#" Inherits="xxxx.intro"%>
<h1>Welcome <%=Resource.Client%></h1>
...Lots more UI stuff
Intro.ascx.cs
public class intro : UserControl
{
public IntroResource Resource { get; set; }
}
Therefore each version of the intro control extends the View with client specific features.
Related
Not sure how to label the title of this question. I have a snippet of re-usable content with a Subscribe Icon + Social Icons. This snippet is used in almost every page on the site through a repeater.
What I want to do is to attach the CurrentDocument.DocumentName to the Subscribe Icon in order to know which page people came from, something like this:
Subscribe However, looks like that doesn't work. This string shows in the address bar when click on the link: www.domain.com/subscribe?p={%%20CurrentDocument.DocumentNamePath%20|(user)|(hash)34ce5eaa55a6a6ad89...%} I figure because CurrentDocument is actually referring to the snippet itself, not the real current page displaying in the browser. Could you help?
Is your repeater transformation aspx? If so, use <%# %>, so <%# CurrentDocument.DocumentName %>
If this is an ASCX transformation it is like a web user control, so you can call C# methods, try this
<%# CMS.MacroEngine.MacroResolver.Resolve("{%CurrentDocument.DocumentName#%}")%>
Or you can do linke in this in ACSX transformation:
<script runat="server">
string test = "";
protected override void OnInit(EventArgs e)
{
test = CMS.MacroEngine.MacroResolver.Resolve("{%CurrentDocument.DocumentName#%}");
}
</script>
<h1><%# test%></h1>
Consult MacroResolver class for other methods
P.S. Sorry I didnt check my answer in Kenitco for the frist time. Just make sure you calling MacroResolver from the right name space.
In the Kentico Documentation I only found the info as below...
Is there any way to access the properties value in the layout as show below? I tried to use macro but it didn't work.
I just want to display the properties value in my custom layout. Any methods other than access through the code? I'm using portal engine, I have no idea how to access the code behind...
The layout is ASCX, so you won't be able to use macros as per your example.
If you just need the value, you can use the GetValue method. There's also GetStringValue, if the type of your property is a string
<% GetStringValue("MyPropertiesValue1", string.Empty); %>
If you need to render the value, you will need to call Page.DataBind() and use a data binding expression. Your layout would look something like this:
<%# GetStringValue("MyPropertiesValue1", string.Empty) %>
<%# GetStringValue("MyPropertiesValue2", string.Empty) %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
Page.DataBind();
}
</script>
None if this is really elegant, so you might want to reconsider your approach.
I want to add a meta tag in my each individual page of life ray. I am could only find meta tag with description which is in the SEO of the pages in Control panel.
<link rel="alternate" href="http://example.com/xyz/abc" hreflang="en-au" />
Please help me out with this. I am unable to find an answer to this.
The best and permanent way is to create custom theme (or modify default one) and add general meta-tags, javascript / css files (which you want to appear on each page of portal) through head section of theme's portal_normal.vm file. However, if you want to restrict these tags for specific page(s) you can still do it through Velocity Objects like public / private layout, admin / user difference, current page name / URL, there are numerous options available.
If you are new to theme design, you can start with: Creating Liferay Themes
The other possible and quick way is to add js / css dynamically using javascript / jQuery as following:
if you are using pure javascript:
window.onload = function(){
loadjscssfile("myscript.js", "js");
loadjscssfile("javascript.php", "js");
loadjscssfile("mystyle.css", "css");
}
Or you can use jQuery:
jQuery(function(){
loadjscssfile("myscript.js", "js");
loadjscssfile("javascript.php", "js");
loadjscssfile("mystyle.css", "css");
});
general method:
function loadjscssfile(filename, filetype){
if (filetype=="js"){
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
}
Reference: http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
Add above code to the javascript section of the root of your pages.
I make security system in mvc application. In MVC it must be done by AuthorizeAttribute and roles string via actions methods.
Could i make this stuff: instead of action resolve I want to make view where html parts are hidden depend on current user permission set (For example: save button are not visible if user not Administrator).
Within your views, you can do conditional checks, such as:
<% if (User.IsInRole("Admin")) { %>
An Admin-only link
<% } %>
In partial views, the User property is not exposed, but you can still do it:
<% var user = HttpContext.Current.User; %>
<% if (user.IsInRole("Admin")) { %>
An Admin-only link
<% } %>
Brian - i don't think this is a good idea to 'hide' the admin parts. you basically then just expose to logic to anyone opening the html in 'view source' mode. it would be better to have an admin view and a 'normal' view and just do a case statement in the contoller action to deliver the appropriate view where required (still not the best option, but far better than hiding fields). better still, have a master view that contains partialviews which are only rendered if it's the correct user type etc..
just my 'view' on the topic..
jim
You can do either A or B
a) Create partial views for the various elements that change and do something like
<% if (HttpContext.Current.User.IsInRole("Administrator"))
{
Html.RenderPartial("AdminStuff");
}
else
{
Html.RenderPartial("RegularStuff");
}
%>
b) Set the role in your viewdata/viewmodel and use it in the code (not recommended as the view should really contain no logic)
In the controller
ViewData["Admin"] = HttpContext.Current.User.IsInRole("Administrator");
In the view
<% if ((bool)ViewData["Admin"]) { %>
<!-- Show admin stuff -->
<% } %>
Thanks to all for your answers. I see that view dynamic render is a bad practic in mvc applications. I'm used to think that there can be some libraries or templates.
BTW When i told to my PM that a string with roles is a common pattern he sad "Hard code!!!!". Now I'm designing some WCF service with will be an "Aplication Authoriser" ))).
Everyone here seems to forget that there is css for such stuff. You can do the thing you want very easily, at least I am doing at already, and it's working flawlessly.
Let me give you a simple example
Make sure your operations buttons/regions have defined css classes
css class: MODULE-OPERATION
e.g.
Module User
Operations: Add, Edit, Delete, List
Add User
Whenever changing (adding/updating/deleting) roles, you generate a css file for each role
e.g.
You decide that only administrators can add users so this css is generated
//admin_css.css
.USER-ADD { display: none; }
Everytime the page is opened you check what role the user has, and based on the role, you load the css file in you header. So your gui correlates to the logic you have in your application without so much hassle.
If I create tabs using one of the Grails GUI options (which one should I use), is it possible to turn tabs on and off, based on the current user? For example only users with a role of admin should see the Manage Users tab. And even anonymous users should see the Main Content tab.
Ideally, I'd like to use Spring Security ACL.
Just to add, sometimes you can add too much logic and coding in the view (GSP). You can push more of the code to the controller by using other options such as the navigation plugin along with the Spring-Security plugin. The nice thing is the view is just cleaner removing condition tags.
grails install-plugin navigation
Then in the controller just use the #Secured annotation. For example I created two tabs with two corresponding controllers.
#Secured(['ROLE_ADMIN'])
class SlidesController {
static navigation = [
group:'tabs', order:10, title:'Users', action:'index'
]
def index = {
.....
}
#Secured(['ROLE_ADMIN'])
class ProgramsController {
static navigation = [
group:'tabs', order:10, title:'Programs & Presentation', action:'index'
]
def index = {
.....
}
In the view:
<head>
... other head elems.
<nav:resources/>
</head>
<body>
<nav:render/>
... Your other stuff
</body>
Tabs automatically appears (would be also useful to make this view a layout GSP).
Yes, it's possible and pretty easy with the Acegi (Spring Security Plugin), see this section of the docs. You'll need to define some roles, and then describe how those roles apply to different URLS. Example (from link above):
/admin/=ROLE_USER
/book/test/=IS_AUTHENTICATED_FULLY
/book/**=ROLE_SUPERVISOR
There is also explanation about exactly how to do this in Grails In Action book.
Spring Security has a nice tag library for this. You can delimit rendering the tabs by using something similar to this:
<sec:authorize access="hasRole('supervisor')">
This content will only be visible to users who have
the "supervisor" authority in their list of <tt>GrantedAuthority</tt>s.
</sec:authorize>
You can just enable the jsp tag as normal:
<%# taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
Read more about it here if you like