I am writing an Orchard theme, and I'd like to be able to locate some of the resources packaged with the theme (images/swfs etc).
What is the best way of doing this?
I've had a look at ResourceManifest files, using builder.Add.DefineResource but I can't seem to find it's counterpart in the view.
Or do I just put the full path in?
Any hints?
Cheers
Carl
In stylesheets, relative paths (from the stylesheet path) should be used.
In views, you should use Url.Content.
If you need to define the new resource (script or stylesheet):
- Create a class inheriting IResourceManifestProvider
- Provide the void BuildManifests(ResourceManifestBuilder builder) method and
- Add all necessary resources via builder.Add().DefineStyle("") or builder.Add().DefineScript(...), just as you noted in your question.
For example:
public class ResourceManifest : IResourceManifestProvider {
public void BuildManifests(ResourceManifestBuilder builder) {
var manifest = builder.Add();
manifest.DefineStyle("MyStyle").SetUrl("mystyle.css");
manifest.DefineScript("MyScript").SetUrl("myscript.js").SetDependencies("jQuery");
}
}
This defines one style and script you can reuse in your views. Urls are relative to /Styles (or /Scripts) folders in your theme/module where the class is located.
If you want to reuse some of resources already defined (in all enabled modules and themes), it's as easy as writing eg.:
...
@{
Style.Require("MyStyle").AtHead();
Script.Require("MyScript").AtFoot();
}
...
inside your .cshtml view file. Example above would inject mystyle.css and myscript.js at appropriate locations (header/footer of the final page).
I slapped together an extension method for a similar problem:
public static string ResourceUrl(this HtmlHelper helper, string resourceType, string resourceName)
{
var manager = helper.Resolve<IResourceManager>();
var settings = new RequireSettings { Type = resourceType, Name = resourceName, BasePath = resourceType };
var resource = manager.FindResource(settings);
var context = new ResourceRequiredContext { Resource = resource, Settings = settings };
var url = context.GetResourceUrl(settings, "/");
return url;
}
Resource Manifest Definition:
manifest.DefineResource("Content", "MyImage").SetUrl("Content/myimage.png");
View Usage:
@Html.ResourceUrl("Content", "MyImage")
It's not well tested, and could probably use some error handling, but its working for me.
Just to be clear, there are a few methods depending on your situation. I'll outline the most common I know.
First of all, there is the inclusion of an external script or stylesheet on your particular part or theme. The standard syntax within a Razor template is this:
@Style.Include("YourPartEdit")
@Script.Require("jQuery")
@Script.Include("YourPartEdit")
The include files will look for that particular resource in the corresponding Style
or Scripts
folder: for @Script.Include("YourPartEdit")
, it will look in the scripts folder for YourPartEdit.js
.
You might have noticed that with Script.Require
you can register a library with Orchard (in this case the registered one is jQuery
), and cause a module to require that particular script.
To do this you create your own implementation of the IResourceManifestProvider
interface, and implement the BuildManifests(ResourceManifestBuilder builder)
method and create a named resource. You can use .AtFoot()
or .AtHead()
to even target where it will go.
Now say you want to reference a particular image, and you want to use Razor to always point to the correct image Url. First of all I recommend placing the image in your Content
folder for your theme (assuming this is a theme related image), and you'll do something along these lines:
<img src=@Url.Content(Html.ThemePath(WorkContext.CurrentTheme, "/Content/your-logo.png")) />
Now, say this is on your Layout.cshtml
page - you'll now successfully serve the image anywhere on the site.
These particular techniques should account for a multitude of situations.
Just a side note:
the solution posted by Adam Anderson works only when the controller class serving the view has the attribute [Orchard.Themes.Themed(true)]