How to create Projector and Query from Migration

Topics: Customizing Orchard, Writing modules
Jul 4, 2012 at 10:37 AM

Hey everyone,

Is it possible to create a query and a projector from the migration file?

Borrie

Developer
Jul 4, 2012 at 11:29 AM

Take a look at the services inside Projector.

Jul 4, 2012 at 11:38 AM

Piedone, I don't know what you mean :)

I'm looking for code like

ContentDefinitionManager.AlterTypeDefinition("Content_Item", builder =>
                builder.Creatable()
                .Draftable()
                .WithPart("CommonPart")
                .WithPart("TitlePart")
                .WithPart("BodyPart"));

But then for a projector

Developer
Jul 4, 2012 at 1:09 PM

In the Projector module (I think the module folder is named Projections) there is a folder called Services. Look at the interfaces: those are that can be injected into any class (also your migrations) and that have methods for query creation. Also, you can create Projections with the injectable IContentManager.

Jul 4, 2012 at 1:23 PM

Piedone,

Thanks again for your answer, do you have some example code? I'm really new to Orchard and MVC..

Borrie

Developer
Jul 11, 2012 at 8:09 PM

Sorry, I haven't done this myself either.

Jul 18, 2012 at 6:18 AM

If the purpose is to move settings from a development environment to a production server, you can use the Import/Export feature to do the job. It would take a LOT of code to get the query, projection and projection widget set up correctly from code.

Jul 18, 2012 at 11:32 AM

jj,

Thanks a lot! That may be exactly what I'm looking for!

Borrie

Aug 6, 2012 at 12:31 PM
Edited Aug 6, 2012 at 2:44 PM

Here's how to add a query with a filter 

in the constructor 

 

private readonly IMenuService _menuService;

        private readonly IContentManager _contentManager;

        private readonly IQueryService _queryService;

        private readonly IWidgetsService _widgetsService;



        public MigrationProjectType(IMenuService menuService, IContentManager contentManager,  IQueryService queryService, IWidgetsService widgetsService)

        {

            _menuService = menuService;

            _contentManager = contentManager;

            _queryService = queryService;

            _widgetsService = widgetsService;

        }

 in the migration 

 public int UpdateFrom7()

        {





            // create a project menu

            var projectMenu = _queryService.CreateQuery("My projects 3");



            var form = new Form { ContentTypes = "Project" };

            var xmlSerializer = new XmlSerializer(form.GetType());

            StringWriter sww = new StringWriter();

            XmlWriter writer = XmlWriter.Create(sww);

            xmlSerializer.Serialize(writer, form);

            var state = sww.ToString();





            projectMenu.FilterGroups[0].Filters.Add(new FilterRecord

            {

                Category = "Content",

                Description = "My filter",

                Position = 0,

                State = state,

                Type = "ContentTypes"

            });



            _contentManager.Publish(projectMenu.ContentItem);





            return 8;

        }



Still havent figured out how to add a projection page, but you can add widgets with the widget service, 

heres how to add a menu widget 

public int UpdateFrom2()

        {
            // create a project menu
            var projectMenu = _menuService.Create("Projects Menu");

            // assign the project items to all current menu items
            foreach (var menuItem in _menuService.Get().Where(x => x.ContentItem.ContentType == "Project"))

            {
                // if they don't have a position or a text, then they are not displayed
                if (string.IsNullOrWhiteSpace(menuItem.MenuPosition) || string.IsNullOrEmpty(menuItem.MenuText))

                {
                    continue;
                }
                menuItem.Menu = projectMenu.ContentItem;

            }

            // create layer part 
            _widgetsService.CreateLayer("SideBar", "desc", "url(\"~\")");

            var defaultLayer = _widgetsService.GetLayers().First(x => x.Name == "Default");

            var widget =  _widgetsService.CreateWidget(defaultLayer.Id, "MenuWidget", "Projects Menu", "2", "Navigation");

            var menuWidget = widget.As<MenuWidgetPart>();

            menuWidget.Record.Menu = projectMenu.ContentItem.Record;

            _contentManager.Publish(menuWidget.ContentItem);

            return 3;

        }

Aug 6, 2012 at 2:41 PM

Figured it out... here's how to a a projection 

 public int UpdateFrom10()
        {
            // create a project menu
            var projectMenu = _queryService.CreateQuery("My projects 11");

            var form = new Form { ContentTypes = "Project" };
            var xmlSerializer = new XmlSerializer(form.GetType());
            StringWriter sww = new StringWriter();
            XmlWriter writer = XmlWriter.Create(sww);
            xmlSerializer.Serialize(writer, form);
            var state = sww.ToString();

            projectMenu.FilterGroups[0].Filters.Add(new FilterRecord
            {
                Category = "Content",
                Description = "My filter",
                Position = 0,
                State = state,
                Type = "ContentTypes"
            });

            _contentManager.Publish(projectMenu.ContentItem);


            var projection = _contentManager.Create<ProjectionPart>("ProjectionPage",
                                t =>
                                    {
                                        t.Record.QueryPartRecord = projectMenu.Record;
                                    });

            projection.As<TitlePart>().Record.Title = "The Team ";
            projection.As<MenuPart>().Record.MenuText = "The Team";
            projection.As<MenuPart>().Record.MenuId = _menuService.GetMenu("Main Menu").Id;
            projection.As<AutoroutePart>().Record.DisplayAlias = "The-Team";
            projection.As<CommonPart>().Record.OwnerId = _membershipService.GetUser("admin").Id;

            _contentManager.Publish(projection.ContentItem);

           
            return 11;
        }

Aug 6, 2012 at 4:54 PM

alistairedmunds,

Thanks so much for your code, this will be a big help!

Borrie

Aug 8, 2012 at 2:57 PM

alistairedmunds,

Could you copy your complete migrations file? I'm having a few errors with the using statement and the constructor code.

Thanks in advance,

Borrie

Aug 8, 2012 at 4:50 PM

alistairedmunds,

Nevermind, I'm managed to get it working, I just have one question about the query:

            projectMenu.FilterGroups[0].Filters.Add(new FilterRecord

            {

                Category = "Content",

                Description = "My filter",

                Position = 0,

                State = state,

                Type = "ContentTypes"

            });

Do you know how to set the actual contenttype it should filter on?

Also do you know how to add a sort criteria?

Borrie

Aug 22, 2012 at 6:37 AM
Edited Aug 22, 2012 at 6:43 AM

Borrie, you can see Orchard Projection Cotroller to investigate how add filter criteria  or sort criteria ( EditPost method )

 QueryPart queryNewsList = _queryService.CreateQuery("News List");

To add actual filter type, add it to state as dictionary param  "ContentTypes"

Dictionary<string, string> filterDictionary = new Dictionary<string, string>();
filterDictionary.Add("Description", "News Content Type");
filterDictionary.Add("ContentTypes", "News");
queryNewsList.FilterGroups.FirstOrDefault().Filters  = new List<FilterRecord>() {
new FilterRecord {
Category = "Content",
Type = "ContentTypes",
Description = "News Content Type",
State =  FormParametersHelper.ToString(filterDictionary)
}};                    }                    };                  };

Add sort criteria 

Dictionary<string, string> sortDictionary = new Dictionary<string, string>();

            sortDictionary.Add("Description", "Publish Date Desc");

            sortDictionary.Add("Sort", "false");

            SortCriterionRecord sortCriterionRecord = queryNewsList.SortCriteria.FirstOrDefault();

            if (sortCriterionRecord == null)

            {

                sortCriterionRecord = new SortCriterionRecord

                {
                    Category = "CommonPartRecord",

                    Type = "PublishedUtc",

                    Description = "Publish Date Desc",

                    Position = 1

                };

                queryNewsList.SortCriteria.Add(sortCriterionRecord);

            }

            sortCriterionRecord.State = FormParametersHelper.ToString(sortDictionary);

 

Aug 22, 2012 at 1:29 PM

mikolalukyanchuk,

Thanks a lot for your answer, could you paste a complete code example of a migration like that? I'm mixing the previous code and your code together and it's not working.

Thanks a lot,

Borrie

Aug 22, 2012 at 6:38 PM
Edited Aug 22, 2012 at 6:46 PM
borrierulez wrote:

mikolalukyanchuk,

Thanks a lot for your answer, could you paste a complete code example of a migration like that? I'm mixing the previous code and your code together and it's not working.

Thanks a lot,

Borrie  

Dependency Injection in Constructor
        public Migrations(IRoleService roleService, IQueryService queryService) {
            _roleService = roleService;
            _queryService = queryService;
        }
 public int UpdateFrom2() {
            QueryPart queryNewsList = _queryService.CreateQuery("News List");

            Dictionary<string, string> filterDictionary = new Dictionary<string, string>();
            filterDictionary.Add("Description", "News Content Type");
            filterDictionary.Add("ContentTypes", "News");
            queryNewsList
                .FilterGroups.FirstOrDefault()
                .Filters  = new List<FilterRecord>() {
                        new FilterRecord {
                            Category = "Content",
                            Type = "ContentTypes",
                            Description = "News Content Type",
                            State =  FormParametersHelper.ToString(filterDictionary)
                        }
                    };

            Dictionary<string, string> sortDictionary = new Dictionary<string, string>();
            sortDictionary.Add("Description", "Publish Date Desc");
            sortDictionary.Add("Sort", "false");
            SortCriterionRecord sortCriterionRecord = queryNewsList.SortCriteria.FirstOrDefault();
            if (sortCriterionRecord == null)
            {
                sortCriterionRecord = new SortCriterionRecord
                {
                    Category = "CommonPartRecord",
                    Type = "PublishedUtc",
                    Description = "Publish Date Desc",
                    Position = 1
                };
                queryNewsList.SortCriteria.Add(sortCriterionRecord);
            }
            sortCriterionRecord.State = FormParametersHelper.ToString(sortDictionary);

            Dictionary<string, string> layoutDictionary = new Dictionary<string, string>();
            layoutDictionary.Add("QueryId", queryNewsList.Id.ToString());
            layoutDictionary.Add("Category", "Html");
            layoutDictionary.Add("Type", "Grid");
            layoutDictionary.Add("Description", "Grid 1 line");
            layoutDictionary.Add("Display", "0");
            layoutDictionary.Add("DisplayType", "Summary");
            layoutDictionary.Add("Alignment", "vertical");
            layoutDictionary.Add("Columns", "1");
            layoutDictionary.Add("GridId", "");
            layoutDictionary.Add("GridClass", "");
            layoutDictionary.Add("RowClass", "");

            LayoutRecord layout = queryNewsList.Layouts.FirstOrDefault();
            if (layout == null) {
                layout = new LayoutRecord() {
                    Category = "Html",
                    Type = "Grid",
                    Description = "Grid 1 line",
                    Display = 0,
                    DisplayType = "Summary",
                };
                queryNewsList.Layouts.Add(layout);
            }
            layout.State = FormParametersHelper.ToString(layoutDictionary);

            return 3;
        }
Oct 3, 2013 at 6:50 AM
hello borrierulez,
I was looking for code like this, and I think it will help me a lot, but i can't understand which code write where.
You wrote to write in constructor, of whose?

If you can write a detailed explanation it will help me a lot.

Thank you,

Reut
Oct 3, 2013 at 10:10 AM
Treut,

I think you have a better chance asking alistairedmunds.

I played with it for a while but actually never finished the projections via migration. It was too much code for just one or 2 projections.

I decided to document the projections that I created via the GUI. That saved me a lot of time.

Sorry that I can't help you more.

Borrie
Oct 3, 2013 at 10:25 AM
Borrie, thank you.
What I need is to filter dynamic when user clicked.
I need to control the filter - every time I need to produce a project or just change an exist project with a specific filter by term.

alistairedmunds, can you please help me?

thank's,
reut
Oct 3, 2013 at 10:32 AM
Treut,

I don't think I understand what you want to accomplish.

Borrie
Oct 3, 2013 at 10:44 AM
I have site with recipes. Every time user click on specific tag ( it's not a real tag in orchard, but a term in taxonomy), I need to filter all recipes with this tag, without doing refresh to the page. Therefor I need to write code that take a string and filter all recipes with this string for term.

It is more understandable?
If not, I will try again.

thank's,
reut