ZF2 to Laminas migration when using Twig for rendering - zend-framework2

I'm migrating my application from ZF2 to Laminas because I need to upgrade to PHP8.1. My issue is that with Zend Framework we were using ZfcTwig to have Twig be the renderer instead of the standard PhpRenderer. And I'm having trouble figuring out how to get a new TwigRenderer to be operational.
I've added mezzio/mezzio-twigrenderer to my composer json and it's downloading the proper vendor files, but it isn't putting the parts into the service manager factories and aliases like ZfcTwig did, and it isn't setting the TwigStrategy in the view_manager.
For ZfcTwig this was done with the following application.config.php:
return \Zend\Stdlib\ArrayUtils::merge([
'modules' => [
'DoctrineModule',
'DoctrineORMModule',
'SwissEngine\Tools\Doctrine\Extension',
'Zend\Form',
'Zend\I18n',
...
// Must be at the end so that JsonStrategy has a higher priority
'ZfcTwig',
],
What am I missing that will allow me to get the Mezzio\Twig\TwigRenderer to take the place of ZfcTwig?
I've tried manually adjusting the composer.lock file to put a laminas component:
"extra": {
"laminas": {
"component": "Mezzio\\Twig\\TwigRenderer"
"config-provider": "Mezzio\\Twig\\ConfigProvider"
}
},
I thought this would add the Mezzio packages to the service manager, but it didn't.

Related

Generate seperate build file for a particular component in angular 7

I am going to develop a very large application using Angular 7 Framework.
I have created a blank angular workspace using
ng new angular-app --create-application=false
And in this workspace I have two angular applications created using the following commands:
ng generate application app-one
ng generate application app-two
Inside each of the two applications, I am going to have multiple components each working independently of each other.
I am looking for a way to create a separate javascript build file for each of the component so as to reduce the build size.
And use each of the separately build js files to use each component as a web component.
Please read what I have already tried to get a better idea.
I have tried the following steps:
Create a repository with prefix custom for custom angular elements:
ng new app-name --prefix custom
Add the angular elements package:
ng add #angular/elements
Create custom element component with encapsulation as native/emulated/none as required:
ng g component my-component --inline-style --inline-template -v Native
Define the custom element in app.modulte.ts
import { Injector} from '#angular/core';
import { createCustomElement } from '#angular/elements';
...
export class AppModule {
constructor(private injector : Injector){
const el = createCustomElement(MyComponent, {injector : this.injector});
customElements.define('my-component',el);
}
ngDoBootstrap(){ }
}
Install ngx-build-plus package for building a single bundle (e. g. for Angular Elements):
npm i ngx-build-plus
Update application's builder section within the angular.json file so that it points to ngx-build-plus:
"builder": "ngx-build-plus:build",
Add script in package.json to run builder:
"build:ngx": "ng build --prod --output-hashing none --single-bundle true"
If required, Combine scripts.js and main.js in the created dist folder by creating a js file "concat_ngx.js":
const fs = require('fs-extra');
const concat = require('concat');
(async function build() {
const files = [
'./dist/<your_project>/scripts.js',
'./dist/<your_project>/main.js',
]
await fs.ensureDir('elements_ngx')
await concat(files, 'elements_ngx/combined-script.js');
})()
Run file to get single js file:
node concat_ngx.js
Use js file in any Angular/Other project to use the custom component created.
But the problem here is I have to change the component bootstrap every time in app-module.ts
I needed an automated way to change the bootstrapping in app-module.ts at runtime.
But the problem here is I have to change the component bootstrap every time in app-module.ts
I needed an automated way to change the bootstrapping in app-module.ts at runtime.
In Angular 7, Add Default or Automatic bootstrapping :-
It is the default way an angular application bootstraps and main.ts holds the starting point of an application.
platformBrowserDynamic().bootstrapModule(AppModule);
For more information see here: -https://medium.com/learnwithrahul/ways-of-bootstrapping-angular-applications-d379f594f604
ng serve -o app-one
or
ng serve -o app-two
For more information see here https://medium.com/#klauskpm/change-the-default-angular-project-27da8fca8721

Serilog : how do you specify a filter expression in config file

I am trying to specify this filter in the appsettings .json file
.Filter.ByExcluding(Matching.FromSource("Microsoft.AspNetCore.Hosting.Internal.WebHost"))
The above syntax works when specified in c#
But trying to specify the same in a json file does not work.
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "Matching.FromSource = 'Microsoft.AspNetCore.Hosting.Internal.WebHost'"
}
}
You need to use Serilog.Expressions for this:
Install-Package Serilog.Expressions
The filter section in appsettings.json looks like:
"Filter": [
{
"Name": "ByExcluding",
"Args": {
"expression": "SourceContext = 'Microsoft.AspNetCore.Hosting.Internal.WebHost'"
}
}
],
In this specific case, I'd suggest considering level overrides as an alternative that will turn off a specific namespace more efficiently.
The answer by Nicholas Blumhardt is correct, but there are some extra details that you might find useful.
If you do not have a piece of source code like the following (during serilog initialization)
.Filter.ByExcluding(Matching.FromSource("Microsoft.AspNetCore.Hosting.Internal.WebHost"))
in one of your .cs files, then the Serilog.Filters.Expressions.dll file will not be loaded, and your filter expression will just fail silently when the config file is loaded. So be sure to refer to .Filter in your .cs source (even if it never gets called)
Another item that is useful for debugging serilog itself (especially config file start ups like this example) is to add serilog debugging of itself to the console
// this is just to check on serilog startup and configuration, problems with serilog itself get written to console
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));
Then run your .cs app in debug mode and check for messages on the console as you initialize serilog from its config file.
It is way easier to do using Filter.ByIncludingOnly your "MyWellKnownNamespace"
That's way easier than trying to figure out exactly what namespace the unwanted messages are coming from:
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(_configuration)
.Filter.ByIncludingOnly( Matching.FromSource("MyWellKnownNamespace") )
.CreateLogger();

Rails 5.1 Angular templateUrl

Question
What do I need to do to get my Angular application to allow me to use the templateUrl property of the Component decorator? When you create a new Rails 5.1 application and use the flag --webpack=angular, it gives you a proof of concept Angular application, but as soon as I started creating more components, I began to recognize that I don't know how to refer to the correct path that the templates are being served. I'm not even sure if they are being served, to be honest.
What I've tried
Tried many different variations of the path, from just the file name all the way to the root of the application, one folder at a time.
Googling for someone else running into the same problem.
include the CommonModule in my imports in app.module.ts.
Background
I'm really used to using the Angular CLI and I don't remember ever having an issue using the templateUrl property. What is different about an Angular CLI project to what's given to you in a Rails 5.1 app in terms of configuration affecting templates? Would I be able to use Angular CLI in a Rails 5.1 app without having to change much of the Rails app itself?
Can be done. But this needs a different webpack loader setup and several minor tweaks.
But first: shopping!
$ yarn add \
html-loader \
awesome-typescript-loader \
angular2-template-loader \
#types/node \
--dev
With all required packages installed replace config/webpack/loaders/angular.js with this:
const {env} = require('../configuration.js');
isProd = env.NODE_ENV === 'production';
module.exports = {
test: /\.ts$/,
use: [
{
loader: 'awesome-typescript-loader',
options: { useCache: !isProd }
},
'angular2-template-loader'
]
};
angular2-template-loader scans your Component decorators for the templateUrl argument and replaces it with something like template: require('...')'. The require() call is the reason for installing #types/node by the way.
awesome-typescript-loader is a bit more optimized than the default ts-loader (which will probably work here as well, but I didn't test it).
So far so good. Next we need to tell webpack how to actually load HTML files. Add config/webpack/loaders/html.js with the following content:
module.exports = {
test: /\.html$/,
loader: 'html-loader',
};
Nothing obscure here. Moving on.
In your Javascript app add type informations for *.html files to app/javascript/hello_angular/html.d.ts:
declare module "*.html" {
const content: string
export default content
}
This tells the TypeScript compiler that require('template.html') returns a string.
Last but not least you have add .html to the recognized extensions in config/webpacker.yml:
default: &default
# ...
extensions:
# ...
- .html
# ...
Now you should be good to go:
import { Component } from '#angular/core';
#Component({
selector: 'hello-angular',
templateUrl: './template.html'
})
export class AppComponent {
name = 'Angular!';
}
Don't forget to restart bin/webpack-dev-server.
Theoretically you could do the same for styleUrls. But this is more tangled with rails/webpacker and you would loose some of it's features.

Karma + Rails: File structure?

When using the karma javascript test library (née Testacular) together with Rails, where should test files and mocked data go be placed?
It seems weird to have them in /assets/ because we don’t actually want to serve them to users. (But I guess if they are simply never precompiled, then that’s not an actual problem, right?)
Via this post: https://groups.google.com/forum/#!topic/angular/Mg8YjKWbEJ8
I'm experimenting with something that looks like this:
// list of files / patterns to load in the browser
files: [
'http://localhost:3000/assets/application.js',
'spec/javascripts/*_spec.coffee',
{
pattern: 'app/assets/javascripts/*.{js,coffee}',
watched: true,
included: false,
served: false
}
],
It watches app js files, but doesn't include them or serve them, instead including the application.js served by rails and sprockets.
I've also been fiddling with https://github.com/lucaong/sprockets-chain , but haven't found a way to use requirejs to include js files from within gems (such as jquery-rails or angularjs-rails).
We ended up putting tests and mocked data under the Rails app’s spec folder and configuring Karma to import them as well as our tested code from app/assets.
Works for us. Other thoughts are welcome.
Our config/karma.conf.js file:
basePath = '../';
files = [
JASMINE,
JASMINE_ADAPTER,
//libs
'vendor/assets/javascripts/angular/angular.js',
'vendor/assets/javascripts/angular/angular-*.js',
'vendor/assets/javascripts/jquery-1.9.1.min.js',
'vendor/assets/javascripts/underscore-min.js',
'vendor/assets/javascripts/angular-strap/angular-strap.min.js',
'vendor/assets/javascripts/angular-ui/angular-ui.js',
'vendor/assets/javascripts/angular-bootstrap/ui-bootstrap-0.2.0.min.js',
//our app!
'app/assets/javascripts/<our-mini-app>/**',
// and our tests
'spec/javascripts/<our-mini-app>/lib/angular/angular-mocks.js',
'spec/javascripts/<our-mini-app>/unit/*.coffee',
// mocked data
'spec/javascripts/<our-mini-app>/mocked-data/<data-file>.js.coffee',
];
autoWatch = true;
browsers = 'PhantomJS'.split(' ')
preprocessors = {
'**/*.coffee': 'coffee'
}
I found this project helpful as a starting point. https://github.com/monterail/rails-angular-karma-example. It is explained by the authors on their blog.
It's an example rails app with angular.js and karma test runner.

Dojo custom build with NLS / localisation

I have a problem implementing a cross domain custom build in Dojo.
The situation is as follows: i have a pretty large application, with a good number of localisation bundles, so basicly the directory structures is like
core\ (my module)
nls\
fr\
en\
....
When building my module the result is a big core.js/core.xd.js file, which, bien sur, does not contain the localisations. In the localisation nls directories (en/fr/etc) i find after the build each bundle builded/minified, and a bigger file for each language, core_fr.js/core_en.fs, which contains only Dojo/Dijit related strings.
so my build script is
layers: [
{
resourceName: "core",
name: "../core/trusted.js",
dependencies: [
"dojo.i18n",
//data
"dojox.data.JsonRestStore",
"dojox.data.XmlStore",
"dojox.rpc.Service",
"dojox.form.FileInput",
...
"core.controller.Fusebox"
],
prefixes: [
["dijit","../dijit"],
["dojox","../dojox"],
["core", "../core"]
]
In the core.controller.Fusebox class i try to load 1 nls
dojo["requireLocalization"]("core", "FuseboxContent");
here it will die, however with
availableFlatLocales is undefined
[Break on this error] var locales = availableFlatLocales.split(",");\r\n
My config in the html file is :
// version build
var djConfig = {
baseUrl: 'https://..../',
modulePaths: { 'core': 'core'},
useXDomain: true,
xdWaitSeconds: 10,
parseOnLoad: true,
afterOnLoad: true,
// debugAtAllCosts: true,
isDebug: true,
locale: "fr"
};
and then
<script type="text/javascript" src="http://xd.woopic.com/dojoroot/1.3.2-xd/dojo/dojo.xd.js.uncompressed.js"></script>
<script type="text/javascript" src="https://..../core/trusted.js.uncompressed.js"></script>
I used the uncompressed for debug, of course.
The problem is that, on runtime, Dojo tries to load my bundles and can not find them, and i would like to embed them in my layer file, so no extra loads will be required.
Can this be achieved? And while we're at it, are there any working sites/examples with cross domain localisations?
UPDATE: i continued my analysis and the problem seems to lay in the fact that i am dynamicaly loading nls, so the build parser can not find the requireLocalization() calls. Therefore the project nls file contains only dojo/dijit related content. However, i added a few bundle loads in a dummy file, and the content of core/nls is still ignored by the builder.
Thanks for any info, i am pretty much at the end of my searches, there isn't much on the net on this subject.
I had a similar issue a few days ago. First of all, you can get around the error by setting the available locales as the 4th parameter of the requireLocalization call.
e.g.
dojo.requireLocalization("core", "FuseboxContent", null, "en,fr");
though you should not have to do that.
Did you try including the localization as follows?
dojo.requireLocalization("core", "FuseboxContent"); // and not dojo["require..."]

Resources