Пример #1
0
        /// <summary>
        /// Adds the AppText admin UI. By default it uses the same virtual path as the API. It can be overridden via the options.
        /// </summary>
        /// <param name="appTextBuilder">AppText components builder</param>
        /// <param name="setupAction">Configures AppText.AdminApp options (optionally)</param>
        /// <returns></returns>
        public static AppTextBuilder AddAdmin(this AppTextBuilder appTextBuilder, Action <AppTextAdminConfigurationOptions> setupAction = null)
        {
            // Register as application part with embedded views
            var mvcBuilder = appTextBuilder.Services.AddMvcCore();
            var assembly   = typeof(AdminController).Assembly;

            mvcBuilder.AddApplicationPart(assembly);

            var options = GetOptions(appTextBuilder.Services, appTextBuilder.ApiConfiguration, setupAction);

            ConfigureServices(appTextBuilder.Services, assembly, options);

            mvcBuilder.AddMvcOptions(mvcOptions =>
            {
                mvcOptions.Conventions.Insert(0, new AppTextRouteConvention(options.RoutePrefix, assembly));
                mvcOptions.Conventions.Add(new AppTextAuthorizationConvention(
                                               options.RequireAuthenticatedUser.HasValue ? options.RequireAuthenticatedUser.Value : false,
                                               options.RequiredAuthorizationPolicy,
                                               assembly));
            });

            // Enable Translations module for our own translations.
            appTextBuilder.AddTranslations();

            // Create AdminApp
            appTextBuilder.InitializeApp(Constants.AppTextAdminAppId, Constants.AppTextAdminAppDescription, new[] { "en", "nl" }, "en", isSystem: true);

            // Import translations (register as IHostedService)
            appTextBuilder.Services.AddHostedService <AppTextAdminInitializer>();

            return(appTextBuilder);
        }
Пример #2
0
        public static AppTextBuilder AddLiteDbStorage(this AppTextBuilder builder, string connectionString)
        {
            builder.Services.AddSingleton(sp => new LiteDatabase(connectionString));
            builder.Services.AddSingleton(sp => new LiteRepository(sp.GetRequiredService <LiteDatabase>()));

            builder.Services.AddScoped <IApplicationStore, ApplicationStore>();
            builder.Services.AddScoped <IContentDefinitionStore, ContentDefinitionStore>();
            builder.Services.AddScoped <IContentStore, ContentStore>();
            builder.Services.AddScoped <IVersioner, Versioner>();

            return(builder);
        }
Пример #3
0
        /// <summary>
        /// Initialize an app in AppText from code.
        /// </summary>
        /// <param name="builder">Apptext components builder</param>
        /// <param name="appId">The App identifier (no spaces)</param>
        /// <param name="displayName">Display name of the app</param>
        /// <param name="languages">Array with available languages</param>
        /// <param name="defaultLanguage">Default language</param>
        /// <param name="isSystem">Indicates if the app should function as a system app. This prevents accidental removal for example.</param>
        /// <returns></returns>
        public static AppTextBuilder InitializeApp(this AppTextBuilder builder, string appId, string displayName, string[] languages, string defaultLanguage, bool isSystem = false)
        {
            builder.Services.Configure <AppInitializerOptions>(o =>
                                                               o.Apps.Add(new App
            {
                Id              = appId,
                DisplayName     = displayName,
                Languages       = languages,
                DefaultLanguage = defaultLanguage,
                IsSystemApp     = isSystem
            }));
            builder.Services.AddHostedService <AppInitializer>();

            return(builder);
        }
Пример #4
0
        /// <summary>
        /// Adds AppText as localization implementation for standard .NET Core Localization functionality. When added to an application, you can use the
        /// standard .NET Core localization facilities (IStringLocalizer, IViewLocalizer), but with AppText as content backend.
        /// </summary>
        /// <param name="appTextBuilder">AppText components builder</param>
        /// <param name="setupAction">Configures AppText.Localization options</param>
        /// <returns></returns>
        public static AppTextBuilder AddAppTextLocalization(this AppTextBuilder appTextBuilder, Action <AppTextLocalizationOptions> setupAction = null)
        {
            var services = appTextBuilder.Services;

            services.AddSingleton <IStringLocalizerFactory, AppTextStringLocalizerFactory>();
            services.AddSingleton <IHtmlLocalizerFactory, AppTextHtmlLocalizerFactory>();
            services.AddSingleton <AppTextBridge>();
            services.TryAddTransient(typeof(IStringLocalizer <>), typeof(StringLocalizer <>));

            services.AddScoped <IEventHandler <ContentItemChangedEvent>, ContentItemChangedEventHandler>();
            services.AddScoped <IEventHandler <AppChangedEvent>, AppChangedEventHandler>();

            // Register for IOptions<AppTextLocalizationOptions>
            if (setupAction != null)
            {
                services.Configure(setupAction);
            }

            // Enable Translations module for our own translations.
            appTextBuilder.AddTranslations();

            // Add initializer as hosted service
            appTextBuilder.Services.AddHostedService <LocalizationInitializer>();

            // Configure RequestLocalizationOptions
            var enrichOptions = setupAction ?? delegate { };
            var options       = new AppTextLocalizationOptions();

            enrichOptions(options);

            if (options.ConfigureRequestLocalizationOptions)
            {
                services.AddOptions <RequestLocalizationOptions>()
                .Configure <IServiceScopeFactory>((locOptions, serviceScopeFactory) =>
                {
                    using (var scope = serviceScopeFactory.CreateScope())
                    {
                        var applicationStore = scope.ServiceProvider.GetRequiredService <IApplicationStore>();
                        var app = AsyncHelper.RunSync(() => applicationStore.GetApp(App.SanitizeAppId(options.AppId)));
                        locOptions.SupportedUICultures   = app.Languages.Select(lang => new CultureInfo(lang)).ToList();
                        locOptions.DefaultRequestCulture = new RequestCulture(CultureInfo.CurrentCulture, new CultureInfo(app.DefaultLanguage));
                    }
                });
            }

            return(appTextBuilder);
        }
Пример #5
0
        public static AppTextBuilder AddNoDbStorage(this AppTextBuilder builder, string baseFolder)
        {
            builder.Services.AddNoDb <App>();
            builder.Services.AddNoDb <ApiKey>();
            builder.Services.AddNoDb <ContentType>();
            builder.Services.AddNoDb <ContentCollection>();
            builder.Services.AddNoDb <ContentItem>();

            builder.Services.AddSingleton <IStoragePathOptionsResolver>(new AppTextStoragePathOptionsResolver(baseFolder));

            builder.Services.AddScoped <IApplicationStore, ApplicationStore>();
            builder.Services.AddScoped <IContentDefinitionStore, ContentDefinitionStore>();
            builder.Services.AddScoped <IContentStore, ContentStore>();
            builder.Services.AddScoped <IVersioner, Versioner>();

            return(builder);
        }
Пример #6
0
        /// <summary>
        /// Adds the Translation Content Type and extra endpoints to support specific translation formats (JSON, .NET RESX, GNU Gettext PO files).
        /// </summary>
        /// <param name="appTextBuilder">AppText components builder</param>
        /// <param name="setupAction">Configures the AppText.Translations add-on</param>
        /// <returns></returns>
        public static AppTextBuilder AddTranslations(this AppTextBuilder appTextBuilder, Action <AppTextTranslationsConfigurationOptions> setupAction = null)
        {
            // First, check existence of TranslationsInitializer. If registered, we assume that this module already has been registered.
            if (appTextBuilder.Services.Any(s => s.ImplementationType == typeof(TranslationsInitializer)))
            {
                return(appTextBuilder);
            }

            // Set options
            var enrichOptions = setupAction ?? delegate { };
            var options       = new AppTextTranslationsConfigurationOptions();

            enrichOptions(options);

            var apiConfiguration = appTextBuilder.ApiConfiguration;

            if (apiConfiguration == null)
            {
                throw new NullReferenceException("The ApiConfiguration of AppText was not set in AppTextBuilder but it is required for the Translations module.");
            }

            // Try to inherit auth options from api configuration when not set
            if (!options.RequireAuthenticatedUser.HasValue)
            {
                options.RequireAuthenticatedUser = apiConfiguration.RequireAuthenticatedUser;
            }
            if (options.RequiredAuthorizationPolicy == null)
            {
                options.RequiredAuthorizationPolicy = apiConfiguration.RequiredAuthorizationPolicy;
            }

            // Add translations initializer.
            appTextBuilder.Services.AddHostedService <TranslationsInitializer>();

            // Add controller routes
            var mvcBuilder = appTextBuilder.Services.AddMvcCore();
            var assembly   = typeof(TranslationsController).Assembly;

            mvcBuilder.AddApplicationPart(assembly);

            // Try to find a route prefix for the AppText api. When found, use that one also for the controllers of this assembly. Otherwise leave empty.
            var translationsPrefix = apiConfiguration != null ? apiConfiguration.RoutePrefix : String.Empty;

            mvcBuilder.AddMvcOptions(mvcOptions =>
            {
                mvcOptions.Conventions.Insert(0, new AppTextRouteConvention(translationsPrefix, assembly));
                mvcOptions.Conventions.Add(new AppTextAuthorizationConvention(
                                               options.RequireAuthenticatedUser.HasValue ? options.RequireAuthenticatedUser.Value : false,
                                               options.RequiredAuthorizationPolicy,
                                               assembly));
            });

            // Add the custom output formatters
            mvcBuilder.AddMvcOptions(mvcOptions =>
            {
                mvcOptions.OutputFormatters.Insert(0, new TranslationResultJsonFormatter());
                mvcOptions.OutputFormatters.Add(new TranslationResultResxFormatter());
                mvcOptions.OutputFormatters.Add(new TranslationResultPoFormatter());
            });
            mvcBuilder.AddFormatterMappings(formatterOptions =>
            {
                formatterOptions.SetMediaTypeMappingForFormat("resx", "text/microsoft-resx");
                formatterOptions.SetMediaTypeMappingForFormat("po", "text/x-gettext-translation");
            });

            return(appTextBuilder);
        }