KalikoCMS / KalikoCMS.Core

Open source content management system (CMS) for the ASP.NET platform.
GNU Lesser General Public License v3.0
145 stars 64 forks source link

1.1.0-beta1 Tested #73

Open dotnetshadow opened 8 years ago

dotnetshadow commented 8 years ago

Hi,

I just wanted to confirm the following issues that I tested with 1.1.0 beta1

var seriesPage = "hello";
SearchManager.Instance.FindSimular(currentPage, 0, 5, false, new[] { "Series", "Category" }).Hits.Where(x => x.MetaData["Series"] != seriesPage);

With this query if the first 5 results contain the metadata series = "hello" then I get 0 results returned? That means I would need to grab say 20 results to make sure I get some results back. I thought the filtering would occur as you are grabbing results?

Another issue is how to use Tags property in FindSimular? Will I need to add MetaData["tags"] ? I thought it would use the item properties?

// Query
SearchManager.Instance.FindSimular(currentPage, 0, 50, false, new[] { "Series", "Tags", "Categories" }).Hits.Where(x => x.MetaData["Series"] != seriesPage);

public class ArticlePage : CmsPage, IIndexable
    {
        [Property("Heading")]
        public virtual StringProperty Heading { get; set; }

        [Property("Content")]
        public virtual HtmlProperty Content { get; set; }

        [Property("Excerpt")]
        public virtual TextProperty Excerpt { get; set; }

        [Property("Description")]
        public virtual StringProperty Description { get; set; }

        [Property("Keywords")]
        public virtual StringProperty Keywords { get; set; }

        [TagProperty("Categories", TagContext = "articlecategories")]
        public virtual TagProperty Categories { get; set; }

        [TagProperty("Tags", TagContext = "articletags")]
        public virtual TagProperty Tags { get; set; }

        [Property("Series")]
        public virtual StringProperty Series { get; set; }

        public IndexItem MakeIndexItem(CmsPage page)
        {
            // Get a strongly typed version
            var typedPage = page.ConvertToTypedPage<ArticlePage>();

            // Create a base index item
            var indexItem = typedPage.GetBaseIndexItem();

            indexItem.Title = typedPage.Heading.Value;
            indexItem.Summary = typedPage.Excerpt.Value;
            indexItem.Content = typedPage.Content.Value;
            indexItem.Tags = typedPage.Tags.ToString();            
            indexItem.Category = "article";            
            indexItem.MetaData["Series"] = typedPage.Series.Value;

            return indexItem;
        }
    }
fschultz commented 8 years ago

Thank you very much for the feedback, much appreciated! I will look into the FindSimular problem.

The request is executed when the call to FindSimular so any filtering will be done on the specified number of hits returned by the function. One way to always fill up X number of hits even after any filtering have been applied would be to fetch - for instance - the first 5 and apply the filter. If less than 5 hits remains, fetch another 5 (6 to 10), apply the filter and repeat if necessary.

For convenience such a feature could be added to the search provider itself in a future version, so that a request looking something like FindSimular(currentPage, 5, x => x.MetaData["a"] == "A") would return the first 5 hits matching the expression given.

As for tags they will be present as a concatenated string (if set in the MakeIndexItem function) in indexItem.Tags.

dotnetshadow commented 8 years ago

With regards to As for tags they will be present as a concatenated string (if set in the MakeIndexItem function) in indexItem.Tags.

I meant that with FindSimular I can't access the tags directly Hits.Where(x => x.Tags <----- doesn't work

The only way I was able to do this was to set in MarkIndexItem indexItem.MetaData["Tags"] = typedPage.Tags.ToString();

Then in FindSimular I can do: .Hits.Where(x => x.MetaData["Tags"] == "hello");

fschultz commented 8 years ago

Thanks for the clarification! I'll look into it.

fschultz commented 8 years ago

I've published a new version; 1.1.0-beta2 where the missing Tags property has been added.

I wasn't able to reproduce the problem with not getting any hits using SearchManager.Instance.FindSimular(currentPage, 0, 5, true). It would be great if you can verify if this problem also occurs in 1.1.0-beta2? Thanks!

This seems to be the problem with stemming again. I had a different category name, once I switched to "Article" I also got 0 hits.

fschultz commented 8 years ago

I've fixed the problem by storing both a non-analyzed category value (for matching categories without stemming) and an analyzed value so that posts will be found through category in search.

I've uploaded a new package KalikoCMS.Search 1.1.0-beta3 that should solve your problem. (The other packages are still in beta2 since nothing in them was changed).

dotnetshadow commented 8 years ago

Thank you so much I will definitely give this a go tomorrow and report back.

Also do you have any idea when you most likely might be able to get some sort of ASP.NET 5 version working because Go Live license has happened. I know httpmodules don't exist anymore, so I'm unsure how I could integrate at least the rendering of my articles in ASP.NET 5, any thoughts?

fschultz commented 8 years ago

I've started looking at an ASP.NET 5 request pipeline to replace the httpmodules, but I currently have a bit of a problem to get the projects compiling correctly. I think handling the request and rendering would be pretty straightforward once I get the projects working. But the major problem is that WebForms have been removed in the new version which will require all admin parts to be converted to MVC. That will require quite a lot of work to fix.

dotnetshadow commented 8 years ago

Hi yes, the webforms definitely impacts the backend. I'm not sure how much of it is tied to rendering unless there are shared libraries needed from webforms. If you have the project handy that I could take a look at perhaps?

fschultz commented 8 years ago

This was far more complex than I expected. I got a pretty good idea how to solve the request pipeline using middleware, but converting the projects to 5.x seems to be a show stopper at the moment as many of the referenced 3rd party libraries don't support 5.x at the moment.

dotnetshadow commented 8 years ago

Yes converting the whole project I would imagine could be a show stopper, will the request pipleline middleware at least allow for the rending of whatever is stored in the database so it can be used in websites?

fschultz commented 8 years ago

The main problem is that much of the internal infrastructure such as the data layer (Telerik's Data Access) doesn't support 5.x at the moment. For rendering to work both the Kaliko.Engine and Kaliko.Mvc projects needs to be brought up to 5.x (removing HttpModules as well as WebControls in the process). Telerik has a pretty good update rate, so hopefully next version might be supporting 5.x projects.

dotnetshadow commented 8 years ago

Not sure if this helps but they have started work on vnext http://www.telerik.com/blogs/telerik-web-ui-products-now-support-vs-2015-rtm

You can also perhaps be specific not to target DNX Core 5.0 and only target DNX 461 as shown here: http://stackoverflow.com/questions/32762350/asp-net-5-vnext-missing-a-using-directive-or-an-assembly-reference-cs0246

fschultz commented 8 years ago

I wondered if this includes Data Access as well as their UI products so I dropped a question to the support.

Thank you very much for the link! I really find the current version numbering quite confusing. So DNX 4.x is ASP.NET 5 but with the full framework rather than only the core which is numbered 5.0??

fschultz commented 8 years ago

With the help of the information you provided I was able to remove most of the compilation errors from the MVC project under DNX 4.x. I got a couple of issues that still remains though:

How to execute the controller (previously available through the IController interface):

            HttpContext.Current.Response.Clear();
            var requestContext = new RequestContext(new HttpContextWrapper(HttpContext.Current), routeData);
            // TODO: FIX ((IController)controller).Execute(requestContext);
            HttpContext.Current.ApplicationInstance.CompleteRequest();

And I'm not quite sure how to inject the custom router:

            // TODO:
            //var route = new CmsRoute("{cmsPageUrl}/{action}", new MvcRouteHandler()) {
            //    Constraints = new RouteValueDictionary { {"cmsPageUrl", new CmsRouteConstraint()} },
            //    Defaults = new RouteValueDictionary { { "action", "Index" } }
            //};

            //RouteTable.Routes.Insert(0, route);

There might need to be some changes to the CmsRoute class.

I'm thinking of skipping these errors for the moment and focus on getting the request pipe running through a middleware instead of httpmodules.

dotnetshadow commented 8 years ago

Yes DNX 4 is the full framework, obviously missing a few things like httpmodules, httpcontext etc and dnx core you can think of as the stuff that should run on linux, mac etc. Most of the time stuff like portable libraries etc will eventually be in dnx core. I know microsoft are writing various dnx core features that will replace a lot of things in dnx full framework i.e. System.Drawing since it previously relied on win32 calls so they can't be used on linux and mac.

It sounds like you have made a great start, with injecting custom route I think you can do somethingk like below: (http://wildermuth.com/2015/3/2/A_Look_at_ASP_NET_5_Part_2_-_Startup)

public void Configure(IApplicationBuilder application, ILoggerFactory loggerfactory) {

application.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

                // Uncomment the following line to add a route for porting Web API 2 controllers.
                // routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
            });

The middleware would be great to have. It would be nice to be able to just render a page in asp.net 5 application from an existing database. The admin section I don't mind if it's still in the old project for the time being.

fschultz commented 8 years ago

Thanks a lot for the info, much appreciated! I suspect I need to rewrite the router as I need a special handler for it (to prevent other requests than for CMS pages to be caught).

One thing that I've run into is that the configuration sections in the web.config no longer works. The following line from the logger returns null where it should return the ConfigSection: var configSection = ConfigurationManager.GetSection("loggers");

Seems like the configuration in ASP.NET 5 is supposed to be done using json, but is there any way to get legacy access to custom sections in web.config to work? It would save me some time since I really hope that I won't have to convert the Core-project nor the Logger at this moment.

dotnetshadow commented 8 years ago

Here are a couple of examples of implementing a custom route, hopefully it can help http://stackoverflow.com/questions/32582232/imlementing-a-custom-irouter-in-asp-net-5-vnext-mvc-6 http://stephenwalther.com/archive/2015/02/07/asp-net-5-deep-dive-routing

You are correct that you configuration section is now done with using default json, but I think you can also import xml, I haven't tried but this article suggests it may be able to: http://whereslou.com/2014/05/23/asp-net-vnext-moving-parts-iconfiguration/

fschultz commented 8 years ago

There's a new feature request up over at Telerik for ASP.NET 5 support in Data Access: http://feedback.telerik.com/Project/114/Feedback/Details/178699-data-access-support-for-asp-net-5

Current version will not work in ASP.NET 5 core but most likely in the full stack version (with some small changes).

The main setback now is that config sections don't seem to be compatible with the new configuration scheme, which means that I need to rewrite (or remove) libraries that uses the older method to store configuration, like the logger for instance.

dotnetshadow commented 8 years ago

Do you have the example of what logger configuration section currently looks like?

fschultz commented 8 years ago

It allows three optional loggers (file, mail and debug):

  <configSections>
    <section name="loggers" type="Kaliko.Configuration.LoggersSection, Kaliko.Logger" />
  </configSections>
...
  <loggers>
    <fileLogger filename="c:\temp\log%yyyy%mm%dd.txt" treshold="Warning" />
    <mailLogger from="website@example.com" to="recipeint@example.com" subject="An error has occured" treshold="Major" />
    <debugLogger treshold="Info" />
  </loggers>

https://github.com/fschultz/Kaliko.Logger

dotnetshadow commented 8 years ago

Perhaps this could help you: http://stackoverflow.com/questions/28846338/how-to-add-configuration-for-log4net-or-any-other-3rd-party-library-in-asp-net

http://dotnetliberty.com/index.php/2015/11/09/asp-net-5-logging-with-log4net/

dotnetshadow commented 8 years ago

Just further information about configs: http://www.strathweb.com/2014/10/using-configr-configuration-source-asp-net-vnext/

fschultz commented 8 years ago

Thanks for the links! Will give it another go to see if I can get the project up and running under full stack.