Reference Model in a Module From Theme

Topics: Customizing Orchard, General, Troubleshooting, Writing modules
Nov 5, 2012 at 3:54 PM

This may not be possible; however, in my effort to move through Orchard I am using Avatar Module.  The issue I have is, I need to find out the file extension that is stored in the Avatar Folder (Media ... / Avatar/[File Name].?)  

I have added the reference

@model Piedone.Avatars.Models.AvatarProfilePart;

This is producing the error:  "Compiler Error Message:  CS1003: Syntax error, '>' expected.

Source Error:  

Line 28:
Line 29:
Line 30:  public class _Page_Themes_TheThemeMachine_View_Layout_cshtml : Orchard.MVC.ViewEngines.Razor.WebViewPage<Piedone.Avatars.Models.AvatarProfilePart;> {
Line 31:
Line 32: #line hidden
Anyone have any suggestions?

Nov 5, 2012 at 4:05 PM

Take the semicolon off, so it's just

@model Piedone.Avatars.Models.AvatarProfilePart
Nov 5, 2012 at 5:09 PM

When I do that I get this Error:

Compiler Error Message: CS0021: Cannot apply indexing with [] to an expression of type 'Piedone.Avatars.Models.AvatarProfilePart'

Line 3:      string CalcuClassify(string[] zoneNames, string classNamePrefix) {
Line 4:          var zoneCounter = 0;
Line 5:          var zoneNumsFilled = string.Join("", zoneNames.Select(zoneName => { ++zoneCounter; return Model[zoneName] != null ? zoneCounter.ToString() : "";}).ToArray());
Line 6:          return HasText(zoneNumsFilled) ? classNamePrefix + zoneNumsFilled : "";
Line 7:      }

Any suggestions?

Nov 5, 2012 at 5:52 PM
Edited Nov 5, 2012 at 5:53 PM

It looks like you have put the @model declaration in your Layout.cshtml. The Layout view defines, well, the general layout for the theme and you probably should change the model for it unless you are really sure you want to do that.

So it sounds like you want to access the ImageUrl property on the AvatarProfilePart as it is rendered. To do this, you'll need to supply your own version of the view Orchard uses (we are effectivly overriding the cshtml provided in Piedone's module with our own). Go to the modules page on the dashboard, and enable "Shape Tracing". Go back to your page with the AvatarProfilePart and at the bottom of the page you'll notice a handle for a panel a bit like firebug which pops up and shows you all the shapes and zones on your page.

Browse through the tree on the left (you might need to start at "Zone [Content]"), and you'll eventually find something like "Parts_AvatarProfilePart". On the right hand side there are a few tabs that let you view and do some manipulation. Expand "Alternate" on the "Shape" tab. This will show you a list of files that Shape Tracing can create which will allow you to override the default shape in Piedone's module. There are variations depending on how you want to override it (see Click create for the first one (Parts.AvatarProfilePart.cshtml), and it will be created in your theme's Views folder. 

Congratulations! You've just overridden a shape!

You can now edit this file, and as long as your theme is enabled it will override the default shape. Helpfully, Shape Tracing will copy the contents of the existing view into the new file, which makes it very easy to make minor adjustments.

Nov 5, 2012 at 6:54 PM

I might have mislead this conversation by using the Layout.cshtml view.  We have a User.cshtml view in our Theme and this view (User.cshtml) does not have the Avatar object inside it.  Is there a way to reference the @model Piedone.Avatars.Models.AvatarProfilePart to get either the ImageURL or the FileExtension?

We need to reference the user's avatar in this view and it then is displayed within out main theme.

Thanks for your help!

Nov 5, 2012 at 7:14 PM
Edited Nov 5, 2012 at 7:21 PM

Ah ok, I got a bit ahead of myself there :) @model is simply a way of saying "When I use 'Model' in this cshtml file, it will be of this type" (well it's a bit more complicated than that, but the point is, it doesn't do any kind of importing of objects). You need to get an actual reference to the current user, and use that to access the AvatarProfilePart.

As it happens, you don't need to use @model in this case, because you can access the current user in a view using WorkContext.CurrentUser, which returns the User content item for the currently logged in user. Because the AvatarProfilePart is attached to the user content item, you would therefore need to do something like this:

     var avatar = WorkContext.CurrentUser.As<AvatarProfilePart>();

to output the URL of the avatar image.

Nov 5, 2012 at 7:37 PM

Getting closer.  We are now getting an error:

Compiler Error Message: CS1928: 'Orchard.ContentManagement.ContentItem' does not contain a definition for 'As' and the best extension method overload 'System.Web.WebPages.StringExtensions.As<TValue>(string)' has some invalid arguments

Source Error:

Line 20: 	
Line 21: 	
Line 22:      var avatar = WorkContext.CurrentUser.ContentItem.As<AvatarProfilePart>();
Line 23: 	
Line 24: 	@Display(avatar.ImageUrl)


not sure if we are supposed to be referencing the namespace?  We have in a @using Piedone.Avatars.Models.AvatarProfilePart; reference and have tried different flavors of that:

@using Piedone.Avatars.Models;
@using Piedone.Avatars;

We also omitted the ContentItem in WorkContext.CurrentUser ... and still got the same error.

Any suggestions?

Again, thanks for your response. 



Nov 5, 2012 at 7:42 PM

You need to add @using Orchard.ContentManagement to pull in the .As<>() extension method (my bad, ReSharper takes care of that for me!)

Try this:

@using Orchard.ContentManagement
@using Piedone.Avatars.Models
    var avatar = WorkContext.CurrentUser.As<AvatarProfilePart>();
Nov 5, 2012 at 7:55 PM


Good to know there is a forum out here with a strong community to respond in time.  This has been bothering me all weekend, wish I would have just reached out instead of beating my head against a wall...

Thanks again, I sincerely appreciate the timely response.

Nov 5, 2012 at 7:56 PM

Haha, we've all been there... Happy Orcharding :)