TYPO3 9.5.3 News Archiv and Route Enhancers - tx-news

I included the RouteEnhancers for the News Plugin and there working as exspected for News List and News Detail Pages. Now i try to implement the DateMenu Archiv and there i have some Problems.
My config.yaml looks like that.
routeEnhancers:
PageTypeSuffix:
type: ForceAppendingSlash
NewsPlugin:
type: Extbase
extension: News
plugin: Pi1
routes:
- routePath: '/news/{page}'
_controller: 'News::list'
_arguments:
page: '#widget_0/currentPage'
- routePath: '/{news_title}'
_controller: 'News::detail'
_arguments:
news_title: news
- routePath: '/archiv/{year}/{month}'
_controller: 'News::archive'
defaultController: 'News::list'
defaults:
page: '0'
requirements:
page: \d+
aspects:
news_title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
My DateMenu.html looks like this:
<ul>
<f:for each="{data.single}" key="year" as="months">
<li>
<ul>
<f:for each="{months}" key="month" as="count">
<li>
<f:link.action pageUid="{listPid}" arguments="{overwriteDemand:{year: year, month: month}}">{year} {month}</f:link.action>
</li>
</f:for>
</ul>
</li>
</f:for>
</ul>
Lists are looking good, but i dont know if there are Urls Cached or something else is Wrong. Will there be a Overview again like in RealUrl so you can see all Cached Urls?

yes, the URLs seem to be cached. i needed to flush the Typo3 and PHP Cache in the "Maintenance" module (under "Adminn Tools"):
BUT i think there are mistakes in your routeEnhancers configuration. they are not well documented in the CoreApiReference, but there is a good description in the changelog:
https://docs.typo3.org/typo3cms/extensions/core/latest/Changelog/9.5/Feature-86365-RoutingEnhancersAndAspects.html
take a look at the generated URLs of the DateMenu - probabbly someting like:
http://yoursite.com
/path/to/newspage/
?tx_news_pi1[controller]=News
&tx_news_pi1[overwriteDemand][year]=2018
&tx_news_pi1[overwriteDemand][month]=10
&cHash=361b6057014505217b6186a508418f6f
so the controller is not 'archive' but 'list'. you need to change that in your config.yaml. also i think you need to configure the arguments for this route:
routePath: '/archive/{year}/{month}'
_controller: 'News::list'
_arguments:
year: overwriteDemand/year
month: overwriteDemand/month
this should transform/get rid of the two &tx_news_pi1[overwriteDemand] parameters.
next, in order to remove the cHash, take a look at the "aspects:" part at the end of the config.yaml file. you have already defined one for "news_title" - and you have to add two more for the new "year" and "month" arguments. there is a multilingual / localized example in the changelog https://docs.typo3.org/typo3cms/extensions/core/latest/Changelog/9.5/Feature-86365-RoutingEnhancersAndAspects.html#staticvaluemapper
below are my entire config.yaml and DateMenu.html files. my setup is:
list and the detail view on two different pages - 14 and 39
i don't use pagination on the listview
i don't want months in the archiv - just years
rootPageId: 1
base: /
baseVariants: { }
languages:
-
title: Deutsch
enabled: true
languageId: '0'
base: /
typo3Language: de
locale: de_CH
iso-639-1: de
navigationTitle: De
hreflang: de
direction: ''
flag: global
-
title: English
enabled: true
languageId: '1'
base: /en/
typo3Language: default
locale: en_US
iso-639-1: en
navigationTitle: En
hreflang: en-US
direction: ''
fallbackType: strict
flag: gb
errorHandling: { }
routes: { }
routeEnhancers:
NewsPlugin:
type: Extbase
limitToPages:
- 14
- 39
extension: News
plugin: Pi1
routes:
-
routePath: '/{news_title}'
_controller: 'News::detail'
_arguments:
news_title: news
-
routePath: '/{year}'
_controller: 'News::list'
_arguments:
year: overwriteDemand/year
defaultController: 'News::list'
defaults:
page: '0'
aspects:
news_title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
year:
type: StaticRangeMapper
start: '2000'
end: '2200'
<div class="news-menu-view">
<ul>
<f:for each="{data.single}" key="year">
<li>
<f:link.action pageUid="{listPid}" arguments="{overwriteDemand:{year: year}}">{year}</f:link.action>
</li>
</f:for>
</ul>
</div>

Related

How to write jmeter test to submit a form within website (Jmeter, ruby -jmeter)

I am writing a load test for my application.
I would like to simulate the following steps:
login
visit several pages
submit a form within the website
I first wrote the login and visit several pages and run them successfully (no errors). When I added the code to submit form, I was getting '404/Not Found error' for the Submit Abstract transaction.
I am grateful to anyone who can provide me direction on how to solve this.
I wrote this test script using ruby then execute to convert it to .jmx file which I use to run headless test in cli.
code for login and visit several pages:
require 'ruby-jmeter'
test do
threads count: 100, rampup: 60, loops: 10, duration: 120 do
defaults domain: 'myapp.herokuapp.com', protocol: 'https'
cookies policy: 'rfc2109', clear_each_iteration: true
transaction 'Page Load Tests' do
user_defined_variables [{name: 'email', value: 'example#example.com'}, {name: 'password', value: 'Pass_w0rd'}]
visit name: 'Visit Login', url: '/users/sign_in' do
extract name: 'csrf-token', xpath: "//meta[#name='csrf-token']/#content", tolerant: true
extract name: 'csrf-param', xpath: "//meta[#name='csrf-param']/#content", tolerant: true
extract name: 'authenticity_token', regex: 'name="authenticity_token" value="(.+?)"'
end
end
http_header_manager name: 'X-CSRF-Token', value: '${csrf-token}'
submit name: 'Submit login', url: '/users/sign_in',
fill_in: {
'${csrf-param}' => '${csrf-token}',
'user[email]' => '${email}',
'user[password]' => '${password}',
'authenticity_token' => '${authenticity_token}'
}
visit name: 'Welcome Page', url: '/static_pages/welcome'
visit name: 'New Abstract Page', url: '/users/2/abstracts/new'
visit name: 'My Profile Page', url:'/users/2/participations/1/profile'
visit name: 'My Own Abstract Page', url:'/users/2/participations/1/abstracts/1'
view_results_in_table
aggregate_report
end.jmx
code for login, visit pages and submit form:
require 'ruby-jmeter'
test do
threads count: 100, rampup: 60, loops: 10, duration: 120 do
defaults domain: 'myapp.herokuapp.com', protocol: 'https'
cookies policy: 'rfc2109', clear_each_iteration: true
transaction 'Page Load Tests' do
user_defined_variables [{name: 'email', value: 'example#example.com'}, {name: 'password', value: 'Pass_w0rd'}]
visit name: 'Visit Login', url: '/users/sign_in' do
extract name: 'csrf-token', xpath: "//meta[#name='csrf-token']/#content", tolerant: true
extract name: 'csrf-param', xpath: "//meta[#name='csrf-param']/#content", tolerant: true
extract name: 'authenticity_token', regex: 'name="authenticity_token" value="(.+?)"'
end
end
http_header_manager name: 'X-CSRF-Token', value: '${csrf-token}'
submit name: 'Submit login', url: '/users/sign_in',
fill_in: {
'${csrf-param}' => '${csrf-token}',
'user[email]' => '${email}',
'user[password]' => '${password}',
'authenticity_token' => '${authenticity_token}'
}
visit name: 'Welcome Page', url: '/static_pages/welcome'
visit name: 'New Abstract Page', url: '/users/2/abstracts/new'
visit name: 'My Profile Page', url:'/users/2/participations/1/profile'
visit name: 'My Own Abstract Page', url:'/users/2/participations/1/abstracts/1'
transaction 'Submit Abstract' do
visit name: 'New Abstract Page', url: '/users/2/abstracts/new' do
extract name: 'csrf-token', xpath: "//meta[#name='csrf-token']/#content", tolerant: true
extract name: 'csrf-param', xpath: "//meta[#name='csrf-param']/#content", tolerant: true
extract name: 'authenticity_token', regex: 'name="authenticity_token" value="(.+?)"'
end
http_header_manager name: 'X-CSRF-Token', value: '${csrf-token}'
submit name: 'Submit Abstract', url: '/users/2/abstracts/new',
fill_in: {
'${csrf-param}' => '${csrf-token}',
'abstract[title]' => 'Lorem Ipsum',
'abstract[main_author]' => '2',
'abstract[co_authors][]' => ["", "1", "3"],
'abstract[corresponding_author_email]' => '${email}',
'abstract[keywords]' => 'word, words',
'abstract[body]' => 'The test directive is a root point, where all the magic starts. Then, using threads method we are telling JMeter what number of users we want to use. The defaults command allows us to specify default options for all our http requests. And, finally,cookies indicates that we need to store cookies and send them with each request.',
'abstract[references]' => '1\r\n2\r\n3',
'authenticity_token' => '${authenticity_token}'
} do
assert 'contains' => 'Abstract submission completed.'
assert 'contains' => 'Lorem Ipsum'
end
end
end
view_results_in_table
aggregate_report
end.jmx
UPDATE PER #DMITRI T SUGGESTION:
EDITED TEST
REQUEST HEADER:
Browser:
Jmeter:
REQUEST BODY:
Browser:
Jmeter:
RESULT: STILL 404 error for the Submit Abstract Transaction
HTTP Status 404 means that the server cannot find the requested resource so most probably your URL is wrong.
So double check that the URL of https://myapp.herokuapp.com/users/2/abstracts/new returns a valid response for the logged in user and if it does - capture the request for creating the new "abstract" using your browser developer tools
Then in JMeter GUI:
Change number of threads, ramp-up period and loop count to 1 in the https://jmeter.apache.org/usermanual/component_reference.html#Thread_Group
Add Debug Post-Processor to your Test Plan (it will allow you to see the values of JMeter Variables)
Add View Results Tree listener to your Test Plan (it will allow to see the request and response details)
Run your test in JMeter GUI, inspect Submit Abstract request details and cross-check it with what you see in the browser developer tools - the requests must be absolutely the same (apart from dynamic parameters)
Fix your JMeter configuration so it would send exactly the same request and it should resolve your issue.

TYPO3 News Routing working but still Hash and other URL parts visible

I have a problem with routing and tx_news in TYPO3 9.5. I have tried all the official examples, but the problem still exists and I can't find out why.
Id' like to have URL like:
...home/news/detail/project-lounge-movetia-2
But I get:
...home/news/detail/project-lounge-movetia-2?tx_news_pi1[day]=11&tx_news_pi1[month]=12&tx_news_pi1[year]=2019&cHash=8fd7057d32ae3e3810b76f0bf4a06e39
The config is standard:
routeEnhancers:
News:
type: Extbase
limitToPages:
- 40
- 54
- 55
extension: News
plugin: Pi1
routes:
- routePath: '/'
_controller: 'News::list'
- routePath: '/page-{page}'
_controller: 'News::list'
_arguments:
page: '#widget_0/currentPage'
- routePath: '/{news-title}'
_controller: 'News::detail'
_arguments:
news-title: news
- routePath: '/{category-name}'
_controller: 'News::list'
_arguments:
category-name: overwriteDemand/categories
- routePath: '/{tag-name}'
_controller: 'News::list'
_arguments:
tag-name: overwriteDemand/tags
defaultController: 'News::list'
defaults:
page: '40'
aspects:
news-title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
page:
type: StaticRangeMapper
start: '1'
end: '100'
category-name:
type: PersistedAliasMapper
tableName: sys_category
routeFieldName: slug
tag-name:
type: PersistedAliasMapper
tableName: tx_news_domain_model_tag
routeFieldName: slug
requirements:
page: '\d+'
The newstitle gets correctly "enhanced", but the rest is still there (hash, id, etc) I have no clue why this happens. I read the manual about routing a lot of times, but I don't get it. :(
It should contain little bit more as showed in their documentation
routeEnhancers:
News:
type: Extbase
limitToPages:
- 104
extension: News
plugin: Pi1
routes:
- routePath: '/'
_controller: 'News::list'
- routePath: '/page-{page}'
_controller: 'News::list'
_arguments:
page: '#widget_0/currentPage'
- routePath: '/{news-title}'
_controller: 'News::detail'
_arguments:
news-title: news
- routePath: '/{category-name}'
_controller: 'News::list'
_arguments:
category-name: overwriteDemand/categories
- routePath: '/{tag-name}'
_controller: 'News::list'
_arguments:
tag-name: overwriteDemand/tags
defaultController: 'News::list'
defaults:
page: '0'
aspects:
news-title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
page:
type: StaticRangeMapper
start: '1'
end: '100'
category-name:
type: PersistedAliasMapper
tableName: sys_category
routeFieldName: slug
tag-name:
type: PersistedAliasMapper
tableName: tx_news_domain_model_tag
routeFieldName: slug
Unwanted params
Actually date params like &tx_news_pi1[day]=20&tx_news_pi1[month]=7 are NOT default ones, which mean that you copied some TS snippet, which includes it or maybe some of your co-workers put it there.
According to News' Humane readable dates documentation search for plugin.tx_news.settings.link.hrDate node in your TypoScript and modify or remove it to get rid date params in single-view links.
Eventually, if you want to keep them, but with human-readable URLs, take a look into the newest documentation of the ext:news which has a sample for proper dates routing with aspects.
I have found the solution. The problem was not the routing, but the raw news URL contained all the additional params {day}{month}{year}. The following SETUP setting turns this off:
plugin.tx_news.settings.link.hrDate = 0
By disabling it, the raw URl generated looks like this:
?tx_news_pi1[action]=detail&tx_news_pi1[controller]=News&tx_news_pi1[news]=486&cHash=
It works now perfectly.
Thanks to biesior for pushing me to the solution!

How to specify nested json body in POST request

I'm trying to set Artillery config to be able to send nested JSON body. This is how my configuration looks like:
config:
target: <URL>
phases:
- duration: 10
arrivalRate: 20
processor: "./input-parser.js"
scenarios:
- flow:
- function: "parseJsonFile"
- post:
url: /workflow-instance
headers:
Content-Type: "application/json"
json:
name: "{{ name }}"
namespace: "{{ namespace }}"
template_name: "{{ template_name }}"
attributes: "{{ attributes }}"
- get:
url: "/workflow-instance/status?name={{ template_name }}&namespace={{ namespace }}"
I have a problem with "attributes" because the content of attributes is:
{ pod_name: 'POD_NAME', port: 'PORT_NUMBER' }
So basically, this will not work:
attributes: "{ pod_name: 'POD_NAME', port: 'PORT_NUMBER' }"
as well as this:
attributes:
pod_name: 'POD_NAME'
port: 'PORT_NUMBER'
I didn't found good examples for this particular case in Artillery docs.
The following workaround worked for me Embedding JSON Data into YAML file
Then you'd have to change your attributes for:
attributes: '{ pod_name: "POD_NAME", port: "PORT_NUMBER" }'
I'm using:
Artillery: 1.7.9
Artillery Pro: not installed (https://artillery.io/pro)
Node.js: v14.6.0
OS: darwin/x64
For future readers looking for hardcoding nested JSON, this worked for me:
...
scenarios:
-
flow:
-
post:
url: "/"
json:
text: {"filter": {"enabled": true}}

Extra / when redirecting a default route

I configured my RouteInitializer as following:
class AppRouteInitializer implements RouteInitializer {
init(Router router, ViewFactory view) {
router.root
..addRoute(
name: 'root',
path: '/lounge_client_demo/web/lounge_client_demo.html',
mount: (Route route) => route
..addRoute(
name: 'lobby',
path: '#lobby',
enter: view('views/LobbyView.html'))
..addRoute(
name: 'chat',
path: '#chat',
enter: view('views/ChatView.html'))
..addRoute(
name: 'default',
defaultRoute: true,
enter: (_) => router.go('lobby', {'param': ':param'}, startingFrom: route, replace: false))
);
}
}
The URL's to lobby and chat:
http://127.0.0.1:3030/lounge_client_demo/web/lounge_client_demo.html#lobby
http://127.0.0.1:3030/lounge_client_demo/web/lounge_client_demo.html#chat
are working as expected. But, when I submit an URL like:
http://127.0.0.1:3030/lounge_client_demo/web/lounge_client_demo.html
or
http://127.0.0.1:3030/lounge_client_demo/web/lounge_client_demo.html#xxx
the rule in the defaultRoute is producing the following wrong URL:
http://127.0.0.1:3030/lounge_client_demo/web/lounge_client_demo/.html#lobby
Am I assuming something wrong here or is it just a bug?
UPDATE: The logging shows that the dot in the URL is being escaped and might be wrongly transformed into the target URL.
2014-01-29 01:20:18.026: FINEST : route /lounge_client_demo/web/lounge_client_demo.html [Route: null]
2014-01-29 01:20:18.035: FINEST : _processNewRoute /lounge_client_demo/web/lounge_client_demo.html
2014-01-29 01:20:18.047: FINEST : route [Route: root]
2014-01-29 01:20:18.055: FINEST : _processNewRoute
2014-01-29 01:20:18.066: FINEST : go /lounge_client_demo/web/lounge_client_demo\.html#lobby
2014-01-29 01:20:18.075: FINEST : route #lobby [Route: root]
2014-01-29 01:20:18.087: FINEST : _processNewRoute #lobby
2014-01-29 01:20:18.099: FINEST : route [Route: default]
2014-01-29 01:20:18.108: FINEST : route [Route: lobby]
UPDATE: I have copied the lounge_client_demo.html into test.file.with.dots.html and get the following URL rewrite:
http://127.0.0.1:3030/lounge_client_demo/web/test/.file/.with/.dots/.html#lobby
The logging shows that every period is being "escaped" by a backslash:
2014-01-30 01:16:28.246: FINEST : go /lounge_client_demo/web/test\.file\.with\.dots\.html#lobby
Possibly a problem with the period character in the route_hierarchical package?!
You should not be including # in the route paths, so just 'lobby', not '#lobby' -- router is doing that for you. If you want to use the fragment (#...) for routing then you need to include the following in your module:
module.value(NgRoutingUsePushState, NgRoutingUsePushState.value(false));
which tells the router to use window.location.hash instead of window.location.path for routing, as well as to listen to window.onHashChange instead of window.onPopState.
That said, you can either do path matching or fragment matching, but not both. So, you'll also need to remove the 'root' route (for path '/lounge_client_demo/web/lounge_client_demo.html'). Once you switch to fragment matching path becomes irrelevant, only stuff after # is passed to the router.
Your route configuration should look something like this:
class AppRouteInitializer implements RouteInitializer {
init(Router router, ViewFactory view) {
router.root
..addRoute(
name: 'lobby',
path: 'lobby',
enter: view('views/LobbyView.html'))
..addRoute(
name: 'chat',
path: 'chat',
enter: view('views/ChatView.html'))
..addRoute(
name: 'default',
defaultRoute: true,
enter: (_) => router.go('lobby', {'param': ':param'}));
}
}

Mustache and Haml

I have got this haml/mustache template:
{{#data}}
ok
{{#items}}
{{#item}}
%b ID: {{id}}
{{/item}}
{{/items}}
{{/data}}
And I have got Illegal nesting: nesting within plain text is illegal Error.
I render it in Sinatra
Mustache.render(haml(:index), hash)
I'm not sure about rendering with Sinatra, but with this command:
cat example.yml foo.haml.mustache | mustache | haml -e
this data file example.yml
---
data:
- items:
- item:
- id: 1
- id: 2
- id: 3
---
and template (foo.haml.mustache ):
{{#data}}
#ok
{{#items}}
{{#item}}
%b ID: {{id}}
{{/item}}
{{/items}}
{{/data}}
I get following result:
<div id='ok'>
<b>ID: 1</b>
<b>ID: 2</b>
<b>ID: 3</b>
</div>
Pls pay attention to indentation level in *.mustache file. Hope this help you.

Resources