I'm new to both .NET development and Umbraco due to recently starting a new role where I will be working heavily with both. As usual before starting development I am looking for some shortcut or helper functions that will enable me to work more productively. One set of helper functions I have found I have included below:
public static string DatedContent(this UrlHelper urlHelper, string contentPath)
{
var datedPath = new StringBuilder(contentPath);
datedPath.AppendFormat("{0}m={1}",
contentPath.IndexOf('?') >= 0 ? '&' : '?',
getModifiedDate(contentPath));
return urlHelper.Content(datedPath.ToString());
}
private static string getModifiedDate(string contentPath)
{
return System.IO.File.GetLastWriteTime(HostingEnvironment.MapPath(contentPath)).ToString("yyyyMMddhhmmss");
}
The functions above are called as follows:
<script src="#Url.DatedContent("~/scripts/product.js")"></script>
The aim of these functions is to automatically version Javascript and CSS files to ensure that the latest versions of each JavaScript and CSS file are pulled through by appending a modified date query string to the end of the file references.
My issue here is, and I apologise that this is such a newbie question, but where do I put this function in Umbraco 7 or is this functionality already supported?
From what I have learnt so far, content pages all have some base properties that include date created and date modified however CSS and Script files do not have these properties so I cannot simply reference these object properties using inline Razor code and condense them with the ToString method as I am doing the functions above.
My first thought was that these functions could be included at the top of the template where the razor code block is included automatically but as I am new to .Net I don't know if this is a standard convention.
Any help would be greatly appreciated.
This is not supported out of the box. Except if you use "Client Depencency" framework. This is a sort of "bundels" framework, similar to the Asp.net framework.
What you do is perfectly possible. Umbraco is still .Net.
2 ways of getting this code in your site:
make a new project, build a DLL and drop the DLL in your umbraco website
put your code in App_code and let IIS build it.
Note: you are checking on EVERY request the modifydate. If you have a busy website, you will want to optimize this. E.g. use a partial using #Html.CachedPartial(...) or using a Macro
Related
I saw some Tutorials on ASP.Net MVC HtmlHelpers and they always included the HTML directly into the SourceCode.
I want to create reusable Controls so that I don't have to write a Login view and the parts of it over and over again over the next projects.
The best thing would be if I could write a DLL and place all my created user controls therein
Some time ago I wrote an application with AngularJS and there were directives
and in them was a templateUrl. Is there something similar in Asp.Net MVC ?
I am using the Razor View Engine and the .Net Framework 4.0.
I know I could use partial views but partial views seem to not work in dlls
"The best thing would be if I could write a DLL and place all my created user controls therein" - You can. There is one little cheat which makes it all work really easily.
When you are writing your html helpers, make sure that you change the namespace to System.Web.Mvc.Html.
If you use the TagBuilder class then you shouldn't be using too much html in your C# code.
Then if you reference your dll in the project, you should be able to access the html helper from your razor view
You can use other namespaces, but you have to have to edit the web.config file inside the Views folder and add a reference to the namespace in the <system.web.webPages.razor> section. By re-using the already referenced namespace, you can save yourself some configuration hassles.
Depending on how many projects and how many developers you want to share the code between, you could also consider a build server product (My team used TeamCity for about 2 years before we needed to pay for a licence). You can then produce your own custom NuGet packages, which lets you share (and manage updates) for partial views, editor templates, html helpers and much more.
I love Bundling and Minification in ASP.NET MVC 4.5 and use it a lot.
However, one small problem is that our "plugins" are hosted on a cookieless domain, which is in a separate project in my Visual Studio solution.
I'm looking for a solution that'll allow our main site to request a bundled and minified JS file containing any number of our plugins from the cookieless site. Something like:
http://my.cookieless.domain/plugins.js?include=alpha&include=bravo,charlie
So far, the best solution I can find is to use a 3rd party bundling and minification library, which seems like overkill considering ASP.NET has one built in.
Is it possible to manually call ASP.NETs bundling/minification process from a within controller action?
public JavaScriptResult Index(IList<string> include)
{
//bundle and minify JS
}
I came across this in search of something similar, here is the solution:
public ActionResult DynamicJs()
{
// Obviously this will be dynamically generated
string javaScript = new Minifier().MinifyJavaScript("alert('Hello world!');");
//returns minified javaScript
return JavaScript(javaScript);
}
Same goes for CSS. You might want to use:
new Minifier().MinifyStyleSheet(styleSheet, new CssSettings { ColorNames = CssColor.Hex }
The Minifier class is a member of Microsoft.Ajax.Utilities, which you can get from the WebGrease Nuget package.
I make use of the bundling features in MVC4 by calling bundles.EnableDefaultBundles();, this allows me to browse to http://website.com/content/css which outputs a singular file of all the CSS files in the /content directory - great.
The issue is I have the following route which loads a blog post from the DB by title: /post/{anything} and in this case {anything} is css (for arguments sake, I can't change it) so the bundling is getting confused and trying to bundling everything in the post directory, which doesn't exist.
Is there any way to exclude a particular URL format or route from being bundled? I think not calling EnableDefaultBundles() would work but does that mean I would have to create bundles for everything manually?
Are you using an old version of the Optimization package? EnableDefaultBundles was removed prior to 1.0. You can still accomplish the equivalent of that method by adding the equivalent js/css DynamicFolderBundles.
I'm having a bit of trouble here.
I want to be able to generate a C# project (and solution) (let's say a C# Console Application) using a template similar to the ones VS2010 uses.
Basically I want to have a method GenerateConsoleApplication which does just that. But since I will need to generate several of these, I want to use a template to populate the Main method of the program.cs class which will be generated alongside the .csproj and app.xml files.
public void GenerateConsoleApplication()
{
var projectName = "MyConsoleApplication";
var projectLocation = "C:\temp";
// what goes here so that it creates a solution Visual Studio that I could use ?
}
I looked up the project template used by VS2010 to generate a C# Console Application and am thinking I could modify it to suit my needs. But I have no idea what I would need to write (code wise) to use the said template and generate all the files of the new solution.
Does anyone know how to do it ? Or if it is even possible ?
I know I could just write the csproj file and the others but I think a template would allow changes more easily.
Just found what I'll need to do.
The problem boils down to the parsing of the templates files.
Once I get the parser, then I can replace the tags with the appropriate values. I wanted to use Visual Studio's parser to do that, and slightly modify the templates it already uses, but it's not possible.
So one has to write its own parser and use it to generate the files.
Then Regex can be use to replace the tags of the template file with the Regex.Replace(String, String, MatchEvaluator) method.
One of the apps I work on is a large ASP.NET 3.5 Web Forms app that is used in the U.S., Central and South Americas, and Europe. We're also starting to do more work with AJAX, and thus we need to settle on a strategy for localizing strings in our JavaScript controls.
For example, we have a control written as a jQuery plugin that formats data into a sortable table. The buttons and table columns need to be localizable.
We're currently using two different approaches to handle this scenario, but I'm not completely satisfied with either.
Write the bulk of the code in a jQuery plugin style, then place a script block on the .aspx page where we'll pull in values from a .resx file and feed them into the plugin code. Here's an example in pseudo code:
<script>
var view;
$(function() {
view = {
columnHeaders: {
productNumber = <%$ Resources:WidgetProductNumber_HeaderText %>,
productDescription = <%$ Resources:WidgetProductDescription_HeaderText %>
}
};
});
</script>
Place the JavaScript in plain .js files with custom tokens in place of strings. We have a handrolled HttpModule that will parse JavaScript files and replace the tokens with values from any existing .resx file whose file name matches the name of the JavaScript file being processed.
Both approaches have problems. I'd prefer to keep our JavaScript code separate from our .aspx pages to make it more unobtrusive and reusable.
The HttpModule approach is clever but a little opaque to developers. I'm also looking to implement a JavaScript bundler called Rejuicer, which is also written as an HttpModule, and getting these to work together seems like it would require customizing the open source code. I'd prefer to use the code as it's written so that we can upgrade it as the project progresses.
Are there any other tried-and-true strategies for approaching this problem in ASP.NET?
It seems that both approaches are a little more complex/cumbersome than necessary. Keep it simple.
1) Using an .ashx, custom http handler, or web service, create a .net object (anonymous, custom -- doesn't matter) that matches the client side JSON object.
2) Populate server side object's properties with the localized values
3) Set the response content type to text/json or text/javascript.
4) Using the JavaScriptSerializer class, serialize the object into the response stream.
From the client side, you have two options:
1) Use an AJAX call to the .ashx/handler/service to set your client side "view" object to the response JSON.
2) Create a script tag with the src="the/path/to/the/serviceOrHandler". In this case you would need to include the js variable declaration in your response output.
Let me know if you need a code sample.
I just stumbled onto this question, and I have another answer to throw into the ring. It isn't my work or anything, but it looks like a fairly elegant solution. It involves writing a localization handler to serve up ASP.NET resources to Javascript. Here are a couple of links:
http://weblog.west-wind.com/posts/2009/Apr/02/A-Localization-Handler-to-serve-ASPNET-Resources-to-JavaScript
http://www.tikalk.com/use-aspnet-resource-strings-within-javascript-files/