I am currently trying to achieve something I think is quite simple:
Changing a background colour based on the role of the logged-in user.
I've got an if/if else setup in the SCSS already, but currently it's just using a hardcoded string.
I also know how to get the string value of the current user's role...
I do not know how to use C# things in SCSS though. When I discovered that '#{}' is used for implementing if/else etc, I naturally tried "#inject" and "#using"... but that didn't work, sadly.
How do I use C# code in SASS?
Generally this is done with a separate class on either the html or body elements. You can do this easily with Razor.
<html class="loggedin">
Then you just define custom overrides based on the selector.
html.loggedin
{
// do your custom stuff in this block.
}
Related
Good evening!
I am currently working on the backend of my application and I need to get a list of all properties of a certain datatype but only the ones in the current page.
listFiltersCms = _umbraco.ContentAtRoot().SelectMany(c => c.Descendants<DataFilters>()).ToList();
This line above gathers all the filters from all the pages, but I want the filters from a specific page (can be currentPage).
I have tried something like this:
var listFiltersCms = _umbraco.AssignedContentItem.SelectMany(c => c.Descendants<DataFilter>()).ToList();
But without any luck :( Any ideas?
Not entirely sure what you mean by "the backend of my application" - are you inside Umbraco or on a public website?
I ask because there is a fairly straightforward way of getting all info on a specific datatype, but it is not really meant to be used on public facing websites. It can be, but it might be taxing on the system as I believe it queries the database directly, which is not ideal.
Anyway, you might want to take a look at the DataTypeService:
https://our.umbraco.com/Documentation/Reference/Management/Services/DataTypeService/Index-v8
And here you can see what options you have for using it (not very explanatory, but I spot a few methods you could probably look into):
https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.Services.IDataTypeService.html
If you decide to use the service in a scenario where there will be a lot of requests, maybe consider caching the output to spare the database.
The way I solved this issue was by getting the page in the correct model. In my case all I had to do was:
(_umbraco.AssignedContentItem as PageModel).FilterCustomMeasures;
There are times when we use same error or success message/checking of some status both in jquery & c#.
For consistency, we can define all message/status flag in as static class and use it wherever needed in c#.
Just an example:
C#
public class MyConstant
{
public static string Admin = "AdminRole";
public static string Approver= "ApproverRole";
}
if(userRole==MyConstant.Admin || userRole==MyConstant.Approver)
{
//more work
}
jquery:
if(userRole=="AdminRole" || userRole=="ApproverRole")
{
//more work
}
In stead hard coding msg/status in jquery, I would prefer approach similar to C#. Would be better to have common place to pull for client/service side.
How can I achieve similar in jquery? Better to say, How can I share common msgs/status flags between jquery & C#. I can think of following options:
Use Database. Cons: hitting DB every time may not be good idea.
Define some classes/property for msgs/status flags separately in jquery. Cons: duplicate; have to ensure all of them in sync.
maybe CMS but not necessarily, will be used in every application
Is there any better approach to share common Message/Error/Status to used across jquery or C#?
Thoughts?
One possible solution is T4 (text templates).
Just imagine a T4 which iterates each enumeration value (why classes of constants? use enumerations!) and creates an object literal like this in JavaScript:
var Roles = { "AdminRole": 1, "ApproverRole": 2 };
If you've never heard about T4, it's the text templating engine behind Visual Studio templates. For example, Entity Framework uses it to generate model classes.
Once you've created the text template, you can sync C# enumeration to JavaScript object literal from Visual Studio when you build your project or running the template manually (right-click on T4 and choose "Run custom tool").
Learn more about T4
I would consider enums for status codes, but you can stay with your strings (no problem). To better address JavaScript part use solution presented here: https://stackoverflow.com/a/2383215/3170952, that is:
my.namespace.Roles = {
ADMIN: "Admin",
APPROVER: "Approver"
}
Then you have one place where you define literals in JS. Better yet, you can weave C# literals into your JS (if you define it in one of ASP.NET MVC views or have other mechanism of incorporating C# into JS files). Then you have one place of definition statically checked during compilation time.
Is there a way to expose Razor syntax and (custom) helpers to people , but say ... not allow them to create code blocks or , to only limit them in the usage of the helpers and to not give them the power to execute pure C# code in the views ?
Any ideas and pointers to similar solutions are welcome !
update:// I would like to give the users the power to write their own HTML and access only to a list of html helpers. Mostly the default ones and the ones i create.
For example i do not want them to be able to execute code within #{ //code } blocks and
Also no using and #model ( not sure about this one)
only have access to #Html.* #if else for foreach
or better yet , give them access only to specific namespaces (this just a thought tho)
update://
After some testing , i found out that RazorEngine does as close as to what i'm trying to do : run the views in isolated environment and add access to specific namespaces.
I would not recommend you doing that. There simply is not an easy and reliable way to give them this ability without compromising the security of your site. If you trust your users then you could do it. If you don't then a templating engine such as DotLiquid is something far more appropriate for this purpose.
There is a project called RazorEngine, built upon Microsoft's Razor, that allows you to parse that syntax without being in the context of returning an MVC view. Here's how it's used:
string template = "Hello #Model.Name! Welcome to Razor!";
string result = Razor.Parse(template, new { Name = "World" });
You can also specify a customized template base, which should allow you to define only the Html Helpers you want to expose to your users:
Razor.SetTemplateBase(typeof(HtmlTemplateBase<>));
string template =
#"<html>
<head>
<title>Hello #Model.Name</title>
</head>
<body>
Email: #Html.TextBoxFor(m => m.Email)
</body>
</html>";
var model = new PageModel { Name = "World", Email = "someone#somewhere.com" };
string result = Razor.Parse(template, model);
you may try to change razor view engine and related classes to check for disallowed situations.
When source is generated (view engine generates a source file to compile ), you have to check it manually (by parsing c# or vb.net code). It is possible, but not feasible (really).
Even if you have managed to parse and check code, you have to identify your code (which is allowed) and customer code (which has restrictions).
At the end you have to accept the fact you can not really disallow anything other than using another template engine.
because
Your customers will find a way to make their views look like yours.
You cannot limit most basic required features like var r = new Random();
You cannot estimate what most basic requirements are
you cannot say No to your customers when they need to use their custom libraries
By the way, you may try another thing. Write a virtual path provider, and convert customer templates written in AviatrixTemplate when requested by runtime. By using this route, you still use razor engine, loose only a slight time when converting (it is one time only). But your AviatrixTemplate won't be hilighted, and you still need to check for disallowed code.
PS: a basic loop may give your users more then you want. for example following code allows creation of a class and call it for one time. they may use fully qualified class name or may use Activator.CreateInstance.
#for (var r = new Random(); r != null; r = null)
{
#r.NextDouble()
}
just do not bother.
I have never done this before, but it sounds like you want to give users the ability to write code and have it compiled for use, yes?
If so, you may want to look into the CSharpCodeProvider class, the RazorTemplateEngine class and the System.CodeCom.Compiler namespace.
Have a look here for some information on those classes:
CSharpCodeProvider: http://support.microsoft.com/kb/304655
RazorTemplateEngine: http://msdn.microsoft.com/en-us/library/system.web.razor.razortemplateengine(v=vs.111).aspx
Whilst looking at a theme I downloaded from the Orchard CMS gallery, I noticed that a Layout.cshtml file had this block of code at the top of the file:
#functions {
// To support the layout classifaction below. Implementing as a razor function because we can, could otherwise be a Func<string[], string, string> in the code block following.
string CalcuClassify(string[] zoneNames, string classNamePrefix)
{
var zoneCounter = 0;
var zoneNumsFilled = string.Join("", zoneNames.Select(zoneName => { ++zoneCounter; return Model[zoneName] != null ? zoneCounter.ToString() : ""; }).ToArray());
return HasText(zoneNumsFilled) ? classNamePrefix + zoneNumsFilled : "";
}
}
I know what the declared function does (calculates which zones are populated in order to return the width of each column), my question is- what is the correct use of the #function block, and when should I ever use it?
The #functions block lets you define utility functions directly in the view, rather than adding them as extensions to the #Html helper or letting the controller know about display properties. You'd want to use it when you can meet these conditions:
The functionality is tied closely to the view and is not generally useful elsewhere (such as "How wide do I make my columns").
The functionality is more than a simple if statement, and/or is used in multiple places in your view.
Everything that the function needs to determine it's logic already exists in the Model for the view.
If you fail the first one, add it as a #Html helper.
If you fail the second one, just inline it.
If you fail the third one, you should do the calculation in your controller and pass the result as part of the model.
Others have explained what #functions does so I won't rehash that. But I would like to add this:
If your view is typed to a viewmodel, I think a viable option would be to move this logic into the viewmodel to avoid cluttering your markup with too much code. Otherwise your views start to look more and more like classic ASP and I don't think anybody wants that.
I don't think there's anything wrong with using #functions or #helper in your view, but once you get beyond a couple of methods in your view, or even if the function is somewhat complicated, it might be worth refactoring to the viewmodel if at all possible. If it's code that can be reused, it may be a good idea to to pull it out into a helper class or an extension to the HtmlHelper class. One thing that is a bummer is realizing you just rewrote a piece of code that already existed because you didn't know it was hidden away in some arbitrary view.
From msdn blogs, #functions block is to let you wrap up reusable code, like the methods and properties
In this particular case, the people who have created the theme you are using probably were trying to keep it as a simple theme (only views, css and images).
If you need to write some code for a theme for Orchard, you have to turn to a module (as stated here: http://docs.orchardproject.net/Documentation/Anatomy-of-a-theme) unless you write this code in the view.
I am not sure it is worth the time to switch from a theme to a module only to get the size of a column.
Basically I'm trying to implement some sort of poor man's Aspect Oriented Programming in C#. I had thought about using a ContextAttribute but they seem only be be bound at the class level. Is there any way that I can put an attribute in such that it will receive the same parameters as the method which it annotates or some way to access the context in which it fired?
I have this code
public void AddUser(User user)
{
var errors = DataAnnotationsValidationRunner.GetErrors(user);
if (errors.Any())
throw new RulesException(errors);
users.Add(user);
}
from which I would like to extract the first 3 lines so I had something like
[Validated]
public void AddUser(User user)
{
users.Add(user);
}
I think you are missing a third component. Most AOP implementations (e.g. Aspect#) rely on a proxy or interceptor to actually execute the code. In your scenario, you lack whichever component needed to 1) know the attribute exists on the method, and 2) trigger the mechanism (or become it) needed to execute the code within the attribute.
Fortunately, there are already many (fairly) simple solutions available in open source. The simplest option I can think of would be to use a compile-time weaver like PostSharp. Grab a copy of that, and in the samples you'll find several examples of exactly what you are trying to do (you'd be interested in the OnMethodInvocationAspect).
The end result is that your code looks exactly like it does in the sample you provided, yet it's also running the code you wish.
Don't know exactly how your solution should look like, but in C# attributes do not execute code as long as you don't request them (as far as I know). And if you query for the attribute, you also have the context. So there is something wrong with your strategy in my opinion.