OrchardCMS / OrchardCore

Orchard Core is an open-source modular and multi-tenant application framework built with ASP.NET Core, and a content management system (CMS) built on top of that framework.
https://orchardcore.net
BSD 3-Clause "New" or "Revised" License
7.43k stars 2.4k forks source link

do we have plan to use Blazor? #2966

Closed infofromca closed 3 years ago

infofromca commented 5 years ago

it seems that after we use Blazor in client (webAssembly), we do not need Liquid.

https://blazor.net/docs/get-started.html

sebastienros commented 5 years ago

Right now the only release you can expect is Razor Components which is a server-side only technology. It's a different programming model than MVC. I don't think it replaces anything like Liquid.

However I am a truly believer that we should create some data oriented Razor Components like Data Sources in Webforms, that could reuse the data from Orchard. This would, like Razor Pages, allow for some nice decoupled website development in Orchard Core.

Skrypt commented 5 years ago

Nice post about the topic I found : https://codedaze.io/introduction-to-server-side-blazor-aka-razor-components/

Fun sample I tried yesterday : https://github.com/stevesandersonms/blazorelectronexperiment.sample

At this point I'd say it would be quite experimental. Though, fun project would be to try making Orchard Core work with Electron at the same time ! 😄

I'd say make it work with .NET Core 3.0 first.

satakane commented 5 years ago

Has this been revisited now that ASP.NET Core 3 and Blazor serverside have been released?

barthamark commented 4 years ago

I took a couple hours trying to add server-side Blazor to Orchard Core and I've succeeded -- I am now able to add Blazor components in any Orchard Core modules or themes. Unfortunately, I had to implement a workaround that we should discuss (see below).

First of all, what you need is to add a modular Startup file and add the server-side Blazor services and register the Blazor hub.

    public class Startup : StartupBase
    {
        public override void ConfigureServices(IServiceCollection services)
        {
            services.AddServerSideBlazor();
        }

        public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
        {
            routes.MapBlazorHub();
        }
    }

Secondly, inside the main Startup file of your web project add app.UseStaticFiles(); before app.UseOrchardCore();. Ultimately, it would be great to not do this or at least do it in the modular startup file but for now I didn't find a better solution.

Finally, make sure that the layout has the <base href="@Href("~/")" /> tag in the head and <script src="_framework/blazor.server.js"></script> in the foot scripts.

Unfortunately, this is not enough to make it work because you will get 404 to the _framework/blazor.server.js file in the browser. It happens because when Blazor creates their file provider (see here and here in the ASP.NET Core source code) it will be overwritten by the OrchardCore static file configuration middleware (see: here).

It would be great to find a solution for this but until then the workaround is to re-register the Blazor embedded file provider in the main Startup file. Since the ConfigureStaticFilesOptions is internal you need to add it somewhere near the Startup file and delete the codes that references other internal settings (which is also not a good idea but it works). Something like this:

    public class BlazorConfigureStaticFilesOptions : IPostConfigureOptions<StaticFileOptions>
    {
        private readonly IWebHostEnvironment _environment;

        public BlazorConfigureStaticFilesOptions(IWebHostEnvironment environment)
        {
            _environment = environment;
        }

        public void PostConfigure(string name, StaticFileOptions options)
        {
            name = name ?? throw new ArgumentNullException(nameof(name));
            options = options ?? throw new ArgumentNullException(nameof(options));

            if (name != Options.DefaultName)
            {
                return;
            }

            // Basic initialization in case the options weren't initialized by any other component
            options.ContentTypeProvider = options.ContentTypeProvider ?? new FileExtensionContentTypeProvider();
            if (options.FileProvider == null && _environment.WebRootFileProvider == null)
            {
                throw new InvalidOperationException("Missing FileProvider.");
            }

            options.FileProvider = options.FileProvider ?? _environment.WebRootFileProvider;

            var provider = new ManifestEmbeddedFileProvider(typeof(IServerSideBlazorBuilder).Assembly);

            options.FileProvider = new CompositeFileProvider(provider, options.FileProvider);
        }
    }

And add the services.TryAddEnumerable(ServiceDescriptor.Singleton<IPostConfigureOptions<StaticFileOptions>, BlazorConfigureStaticFilesOptions>()); line after the services.AddOrchardCms(); in the ConfigureServices method.

Please let me know your thoughts.

jtkech commented 4 years ago

As i have time i will look at it, i need to learn Blazor first ;)

sebastienros commented 4 years ago

What would be the goal?

barthamark commented 4 years ago

@sebastienros any of them, I don't have an exact goal yet, I'm just exploring the possibilities. Basically, I want to know how deep I can go using Blazor components in Orchard Core. Even if it's a SPA using webassembly or it's a ContentPart editor shape using Blazor components on Admin. For now, I didn't try using Webassembly because it's not released yet but server-side Blazor would make sense.

miguelhasse commented 4 years ago

How about having a Blazor version of Orchard Core's back-office. It would also be nice to have a Blazor Component to render liquid pages.

hishamco commented 4 years ago

I like the idea, but not all of us like Blazor, some prefer Razor, AngularJS .. etc

sturlath commented 4 years ago

What I'm looking at is to create a modular Blazor application witch is the reason I ended up looking at the Orchard Core Framework. Hopefully there will be some way to marry these two. Does this make sense or should I be looking at something else?

Skrypt commented 4 years ago

Should work but there's nothing so far planned about it I heard of. This is kind of a choice to make when building a module to use Vue.js or Angular or Blazor to make it work. We need to have some prototypes built first and see from there.

sebastienros commented 4 years ago

There is a modular framework for Blazor called Octane that you could look at. https://www.oqtane.org/

psijkof commented 4 years ago

I would like to build either a full blazor app, as an orchard core module and with other features and settings create a recipe to enable it as an app, multitenant mode. Or use razor components in a regular mvc/razor pages app, modular, multitenant fashion.... Oqtane is blazor only, and not as flexible and open as orchard. The apps/modules I'm enabling through my recipes and exposing them multitenant, should allow me to use everything there is in the asp.net core framework....

jersiovic commented 4 years ago

We are developing our ERP with Orchard Core because we want its modularity and because it allows to have different frontend technology on each module. It ensures us a gradual migration of our modules to future front end technologies. That's why I would like to see Blazor supported

barthamark commented 4 years ago

I've created a sample Orchard Core CMS website (not decoupled) with two sample modules using server-side Blazor. I've added code comments almost everywhere so you will see what steps are required to make it work when you implement your own. Since I am not sure what scenarios you'd like to support this sample is very simple so let me know what you have in your mind. https://github.com/barthamark/Orchard-Core-Blazor-Sample

Since Orchard Core websites can be modularized and server-side Blazor can be integrated (with workarounds, see my comment) we can add Blazor components to Orchard Core modules. This way we can enable or disable some features implemented using Blazor. As for not server-side Blazor the approach is completely different because you will build an SPA using Blazor and use Orchard Core as backend which is separated.

Please let me know if it helps.

sebastienros commented 4 years ago

@barthamark do you want to demo it and talk about what it enables?

barthamark commented 4 years ago

Yes, sure. Let's talk about this. I'll go to one of the next meetings and demo it. Thanks.

agriffard commented 4 years ago

@barthamark Do you still want to make a demo during a meeting?

barthamark commented 4 years ago

Yes, let's do it next week.

barthamark commented 4 years ago

Unfortunately, I have to postpone this demo to next week because I got the cold and can't speak too much. Until next week, please let me know if you have a specific idea about where you'd find it useful to write modularized server-side Blazor components so I can create a couple more examples if needed.

agriffard commented 4 years ago

I would also love to see a POC that uses Blazor WebAssembly.

See today's announcement: https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-2-release-now-available/

It would be a Blazor Wasm app that calls some REST or GraphQL apis exposed by an Orchard Instance. Kind of like what @OrchardSkills made with the Angular 8 Sample but with Blazor.

I created an issue about an Helper Library that would help to abstract the GraphQl calls to OC: #5434

sebastienros commented 4 years ago

My new recommendation: Use Blazor Wasm if you want, in the admin or the frontend. But we shouldn't change Orchard in any way to add custom support for it, even less Blazor Server.

hishamco commented 4 years ago

It could be a community driven project

daveblack101 commented 4 years ago

@barthamark meeting's now in case you are available

kevinvdm88 commented 4 years ago

Blazor Webassembly 3.2.0 is now fully released. https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-now-available/

Do you guys have plans to add a testproject with it in Orchard ?

hishamco commented 4 years ago

@kevinvdm88 we could add this into https://github.com/OrchardCoreContrib/OrchardCoreContrib.Themes

ns8482e commented 4 years ago

My new recommendation: Use Blazor Wasm if you want, in the admin or the frontend. But we shouldn't change Orchard in any way to add custom support for it, even less Blazor Server.

We could use Orchard Core as Back-end Server and Blazor Wasm as standalone Front-end web application ( not as orchard module) - It could be Good candidate for How-to guide.

deanmarcussen commented 4 years ago

We could use Orchard Core as Back-end Server and Blazor Wasm as standalone Front-end web application ( not as orchard module) - It could be Good candidate for How-to guide.

Would be a Great How-to guide, and the right idea for seperation of concerns (IMHO) between back end Orchard Core and Blazor as a Front End

Skrypt commented 4 years ago

https://blog.stevensanderson.com/2019/11/01/exploring-lighter-alternatives-to-electron-for-hosting-a-blazor-desktop-app/

Just wanted to include a reference to this nice post on this topic. For example, if someone wanted to work on a Blazor admin dashboard app. This could be somehow quite experimental but also a good thing to try.

OrchardSkills commented 4 years ago

I have been experimenting with Blazor

Blazor Web Assembly with Orchard Core

Other Orchard Core Blazor Videos: https://www.youtube.com/c/OrchardSkills/videos

xperiandri commented 3 years ago

So instead of https://github.com/OrchardCMS/OrchardCore/issues/2966#issuecomment-555506779 I added


public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider)
{
    app.UseStaticFiles(new StaticFileOptions
    {
        FileProvider = new ManifestEmbeddedFileProvider(typeof(IServerSideBlazorBuilder).Assembly),
    });

    routes.MapBlazorHub();
}

and it works perfect for all tenants

sebastienros commented 3 years ago

@xperiandri can you explain what you can accomplish with that?

xperiandri commented 3 years ago

I render Blazor component on some page like this <component type="typeof(Options)" render-mode="ServerPrerendered" /> In order to work it requires <script src="_framework/blazor.server.js"></script> So my code above makes it work for all tenants

ns8482e commented 3 years ago

@sebastienros That's because StaticFileOptions are explicitly defined in OrchardCore instead of Resolved from DI by StaticMiddleware - resulted in IPostConfigureOptions<StaticOptions> not being called.

This can be easily fixed in OC, will create PR soon.

psijkof commented 1 year ago

loading '_framework/blazor.server.js' works now by configuring the staticfileoptions with a ManifestEmbeddedFileProvider pointing to the blazor assembly.

How would I achieve for also resolving the '_content/etc.css' file from a RCL?

xperiandri commented 1 year ago

@psijkof check obj folder structure and inspect embedded resources of the assembly

websitewill commented 7 months ago

@psijkof @xperiandri did you figure this out and can share? I think I am in the same boat - when I publish my site, I see all of the js+wasm files in the wwwroot folder, but I am not able to lad them. Oddly, _framework/blazor.web.js (which doesn't actually exist) is served, but the actual published output files such as the blazor.webassembly.js, dotnet.js, or the wasm files all result in 500 errors.

I suspect something I have to do with UseStaticFiles (where I call it, what I pass to it, something). But no idea what...

I am using Blazor8, BTW.

TIA!

xperiandri commented 7 months ago

As far as I remember I had to adjust the path of js according to module name