Custom Site Recipe

Topics: Customizing Orchard
Sep 11, 2014 at 11:19 PM
I have the following in my site recipe but for some reason an instance of the speedbump content type isn't being created. Any ideas?

<Metadata>
<Types>
  <Page ContentTypeSettings.Draftable="True" TypeIndexing.Indexes="Search">
    <TagsPart />
    <LocalizationPart />
    <TitlePart/>
    <AutoroutePart />
    <MenuPart />
  </Page>
  <Speedbump ContentTypeSettings.Creatable="True" ContentTypeSettings.Draftable="True" TypeIndexing.Indexes="Search">
    <TitlePart />
    <BodyPart />
  </Speedbump>
  <BlogPost ContentTypeSettings.Draftable="True" TypeIndexing.Indexes="Search">
    <CommentsPart />
    <TagsPart />
    <LocalizationPart />
    <TitlePart/>
    <AutoroutePart />
  </BlogPost>
</Types>
<Parts>
  <BodyPart BodyPartSettings.FlavorDefault="html" />
</Parts>
</Metadata>

<Settings />

<Migration features="*" />

<Command>
layer create Default /LayerRule:"true" /Description:"The widgets in this layer are displayed on all pages"
layer create Authenticated /LayerRule:"authenticated" /Description:"The widgets in this layer are displayed when the user is authenticated"
layer create Anonymous /LayerRule:"not authenticated" /Description:"The widgets in this layer are displayed when the user is anonymous"
layer create Disabled /LayerRule:"false" /Description:"The widgets in this layer are never displayed"
layer create TheHomepage /LayerRule:"url '~/'" /Description:"The widgets in this layer are displayed on the home page"
widget create HtmlWidget /Title:"First Leader Aside" /Zone:"TripelFirst" /Position:"5" /Layer:"TheHomepage" /Identity:"SetupHtmlWidget1" /UseLoremIpsumText:true
widget create HtmlWidget /Title:"Second Leader Aside" /Zone:"TripelSecond" /Position:"5" /Layer:"TheHomepage" /Identity:"SetupHtmlWidget2" /UseLoremIpsumText:true
widget create HtmlWidget /Title:"Third Leader Aside" /Zone:"TripelThird" /Position:"5" /Layer:"TheHomepage" /Identity:"SetupHtmlWidget3" /UseLoremIpsumText:true
site setting set baseurl
menu create /MenuName:"Main Menu"
page create /Slug:"welcome-to-orchard" /Title:"Welcome to Orchard!" /Path:"welcome-to-orchard" /Homepage:true /Publish:true /UseWelcomeText:true

speedbump create /Slug:"valid-url" /Title:"Valid URL" /Path:"valid-url" /Homepage:true /Publish:true /UseWelcomeText:false

menuitem create /MenuPosition:"0" /MenuText:"Home" /Url:"~/" /MenuName:"Main Menu"
widget create MenuWidget /Title:"Main Menu" /RenderTitle:false /Zone:"Navigation" /Position:"1" /Layer:"Default" /Identity:"MenuWidget1" /MenuName:"Main Menu"
theme activate "The Theme Machine"
</Command>
Developer
Sep 11, 2014 at 11:34 PM
One reason could be that you didn't declare that content type in the <Types> section.
Perhaps you intend to create that type via the "speedbump create" command, but since you didn't show its implementation its kinda hard to tell why it doesn't work.
Sep 11, 2014 at 11:38 PM
But I did include it in the <Types> section in the recipe file.

<Speedbump ContentTypeSettings.Creatable="True" ContentTypeSettings.Draftable="True" TypeIndexing.Indexes="Search">
    <TitlePart />
    <BodyPart />
    <CommonPart />
  </Speedbump>
I added the CommonPart because it wouldn't let me create the Speedbump in the UI without it for some reason. So now I can create the Speedbump once inside the site but the recipe should create the speedbump for me with the following:

Speedbump create /Slug:"valid-url" /Title:"Valid URL" /Path:"valid-url" /Homepage:true /Publish:true /UseWelcomeText:false
Developer
Sep 11, 2014 at 11:45 PM
You're right, I missed it (that's what happens when you skip lunch).

Are you on 1.x? If so, then you should mark your content type as being Listable, not just Creatable.
Sep 11, 2014 at 11:53 PM
Sorry you skipped lunch. How would I go about making it listable?

would the following work?

ContentTypeSettings.Listable="True"
Developer
Sep 11, 2014 at 11:59 PM
Yes, that should do it. To be sure, you can manually create your content type through the dashboard, then use the Export tool to export your content type definition, and inspect the XML file.
Developer
Sep 12, 2014 at 3:36 AM
Stupid question: Who created the "speedbump create" command?
If you (emeraldarcher) didn't create it. That's the problem. It's not a normal Orchard command.
Sep 12, 2014 at 4:10 PM
ah, so I have to create the command? How would I go about doing that?
Sep 12, 2014 at 5:49 PM
Edited Sep 12, 2014 at 5:51 PM
I created the command in my module but it still won't create the speedbump. Do I need to create the command within the setup module?

Command:

namespace Speedbump.Commands
{
public class SpeedbumpCommands : DefaultOrchardCommandHandler
{
    private readonly IContentManager _contentManager;
    private readonly IMembershipService _membershipService;
    private readonly ISiteService _siteService;
    private readonly IMenuService _menuService;
    private readonly INavigationManager _navigationManager;
    private readonly IAuthenticationService _authenticationService;

    public SpeedbumpCommands(
        IContentManager contentManager,
        IMembershipService membershipService,
        IAuthenticationService authenticationService,
        ISiteService siteService,
        IMenuService menuService,
        INavigationManager navigationManager)
    {
        _contentManager = contentManager;
        _membershipService = membershipService;
        _siteService = siteService;
        _menuService = menuService;
        _navigationManager = navigationManager;
        _authenticationService = authenticationService;
    }

    [OrchardSwitch]
    public string Slug { get; set; }

    [OrchardSwitch]
    public string Title { get; set; }

    [OrchardSwitch]
    public string Path { get; set; }

    [OrchardSwitch]
    public string Text { get; set; }

    [OrchardSwitch]
    public string Owner { get; set; }

    [OrchardSwitch]
    public bool Homepage { get; set; }

    [OrchardSwitch]
    public bool Publish { get; set; }

    [OrchardSwitch]
    public string MenuText { get; set; }

    [OrchardSwitch]
    public string MenuName { get; set; }

    [CommandName("speedbump create")]
    [CommandHelp("speedbump create [/Slug:<slug>] /Title:<title> /Path:<path> [/Text:<text>] [/Owner:<username>] [/MenuName:<name>] [/MenuText:<menu text>] [/Homepage:true|false] [/Publish:true|false]" + "Creates a new speedbump")]
    [OrchardSwitches("Slug,Title,Path,Text,Owner,MenuText,Homepage,MenuName,Publish")]
    public void Create()
    {
        if (String.IsNullOrEmpty(Owner))
        {
            Owner = _siteService.GetSiteSettings().SuperUser;
        }

        var owner = _membershipService.GetUser(Owner);
        _authenticationService.SetAuthenticatedUserForRequest(owner);

        var speedbump = _contentManager.Create("Speedbump", VersionOptions.Draft);
        speedbump.As<TitlePart>().Title = Title;
        speedbump.As<ICommonPart>().Owner = owner;

        if (!String.IsNullOrWhiteSpace(MenuText))
        {
            var menu = _menuService.GetMenu(MenuName);

            if (menu != null)
            {
                var menuItem = _contentManager.Create<ContentMenuItemPart>("ContentMenuItem");
                menuItem.Content = speedbump;
                menuItem.As<MenuPart>().MenuPosition = Position.GetNext(_navigationManager.BuildMenu(menu));
                menuItem.As<MenuPart>().MenuText = MenuText;
                menuItem.As<MenuPart>().Menu = menu;
            }
        }

        // (PH:Autoroute) Hackish way to leave Slug and Homepage switches intact without requiring a dependency on Autoroute. This may throw an Exception with
        // no AutoroutePart. But it means that normal setup recipes will still be able to give you a homepage without issue.
        if (Homepage || !String.IsNullOrWhiteSpace(Slug))
        {
            dynamic dspeedbump = speedbump;
            if (dspeedbump.AutoroutePart != null)
            {
                dspeedbump.AutoroutePart.UseCustomPattern = true;
                dspeedbump.AutoroutePart.CustomPattern = Homepage ? "/" : Slug;
            }
        }

        if (Publish)
        {
            _contentManager.Publish(speedbump);
        }

        Context.Output.WriteLine(T("Speedbump created successfully.").Text);
    }
}
}
Sep 12, 2014 at 6:29 PM
My command works when running it through the command prompt but not within the recipe. I altered it to be more basic but it still doesn't work from within the recipe.

Recipe:

<Command>
speedbump create /Title:"Valid URL" /Publish:true
speedbump create /Title:"Invalid URL" /Publish:true
</Command>

Command:

namespace Speedbump.Commands
{
public class SpeedbumpCommands : DefaultOrchardCommandHandler
{
    private readonly IContentManager _contentManager;
    private readonly IMembershipService _membershipService;
    private readonly ISiteService _siteService;
    private readonly IMenuService _menuService;
    private readonly INavigationManager _navigationManager;
    private readonly IAuthenticationService _authenticationService;

    public SpeedbumpCommands(
        IContentManager contentManager,
        IMembershipService membershipService,
        IAuthenticationService authenticationService,
        ISiteService siteService,
        IMenuService menuService,
        INavigationManager navigationManager)
    {
        _contentManager = contentManager;
        _membershipService = membershipService;
        _siteService = siteService;
        _menuService = menuService;
        _navigationManager = navigationManager;
        _authenticationService = authenticationService;
    }

    [OrchardSwitch]
    public string Title { get; set; }

    [OrchardSwitch]
    public string Text { get; set; }

    [OrchardSwitch]
    public string Owner { get; set; }

    [OrchardSwitch]
    public bool Publish { get; set; }

    [CommandName("speedbump create")]
    [CommandHelp("speedbump create /Title:<title> [/Text:<text>] [/Owner:<username>] [/Publish:true|false]" + "Creates a new Speedbump")]
    [OrchardSwitches("Title,Text,Owner,Publish")]
    public void Create()
    {
        if (String.IsNullOrEmpty(Owner))
        {
            Owner = _siteService.GetSiteSettings().SuperUser;
        }

        var owner = _membershipService.GetUser(Owner);
        _authenticationService.SetAuthenticatedUserForRequest(owner);

        var speedbump = _contentManager.Create("Speedbump", VersionOptions.Draft);
        speedbump.As<TitlePart>().Title = Title;
        speedbump.As<ICommonPart>().Owner = owner;

        var text = String.Empty;

            if (!String.IsNullOrEmpty(Text))
            {
                text = Text;
            }

        speedbump.As<BodyPart>().Text = text;
        if (Publish)
        {
            _contentManager.Publish(speedbump);
        }

        Context.Output.WriteLine(T("Speedbump created successfully.").Text);
    }
}
}
Coordinator
Sep 12, 2014 at 6:48 PM
Have you enabled the feature containing the command in a previous recipe step ?
Sep 12, 2014 at 6:49 PM
um, nope...my bad lol
Sep 12, 2014 at 7:00 PM
I tried enableing the feature within my recipe but it still doesn't work. I just added the feature to the list of features to be enabled.
Nov 17, 2014 at 8:00 PM
sfmskywalker wrote:
Are you on 1.x? If so, then you should mark your content type as being Listable, not just Creatable.
Where is this Listable extension? I can't find it in the code anywhere.
Developer
Nov 17, 2014 at 8:14 PM
It's a setting on the Content Type edit screen. Go to Content Definition -> Content Types -> edit your content type. You'll find a bunch of checkboxes there, including Listable.
Nov 17, 2014 at 9:35 PM
That's what I saw in some screenshots you had in your blog. But I don't see it anywhere in anything I have access to. Thinking is was something in my codebase, I went to tryorchard and took a look there. Tried creating a new type, but nothing. Even for the Projection Content Type, all I see is Creatable and Draftable check boxes. Am I losing my mind? We're talking 1.8.1, right?
Developer
Nov 17, 2014 at 9:51 PM
I was talking about 1.x, hence my question:
sfmskywalker wrote:
Are you on 1.x? If so, then you should mark your content type as being Listable, not just Creatable.
:)
Nov 17, 2014 at 10:12 PM
Ok, I'm going braindead. 1.8.1 falls into the category of 1.x, yes? Yet, I don't see Listable.
Really, I've been doing this for decades ... I'm not nearly as stupid as I'm making myself out to be! :-)
Developer
Nov 17, 2014 at 10:56 PM
Ah, that's where you went wrong my friend. 1.8.1 is an older release, branched away from 1.x.
1.x contains the latest and greatest features, from which a 1.9 branch will soon sprout.
1.x is the trunk, and 1.8.1 is a release, outdated the very minute it was released. :)
Nov 18, 2014 at 4:49 AM
Fabulous! I would much rather know that I fell prey to a branch labeling convention than that early-onset Alzheimer's was kicking in. Thanks, Sipke..I'll grab that branch first thing in the morning. (Tuesday meetings will make so much more sense now!)
Developer
Nov 18, 2014 at 6:53 AM
No worries! See you tomorrow. :)