Initial commit - Typo3 11.5.41

This commit is contained in:
Matteo Gallo
2026-07-03 17:53:31 +02:00
commit 5ca4743197
6811 changed files with 568848 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
.. include:: /Includes.rst.txt
.. _limitCE:
======================
Limit content elements
======================
If you want to limit the available content element types for news records, you have two options to configure that with Page TSConfig:
1. ``TCEFORM`` ::
TCEFORM.tt_content.CType.removeItems = html,bullets,div,menu_subpages
2. Backend Layout settings: ::
mod.web_layout.BackendLayouts.1.config.backend_layout.rows.1.columns.1.allowed = textmedia,textpic
TCAdefaults.tt_content.CType = textmedia
With the first line you change the allowed CTypes for the backend layout that applies to your news sysfolder.
The second line sets the default CType to prevent an error with e.g. ``INVALID VALUE ("text")``
.. Hint::
Regardless which option you choose, you need to wrap the TSConfig code with a TypoScript condition to limit the restriction to the sysfolder(s) where your news records reside, e.g with ``[123 in tree.rootLineIds]``
.. Hint::
Option 2 has the advantage, that if you want to allow only a very small number of content element types, you don't need to remove explicitly every CType. It's rather a whitelist approach.

View File

@@ -0,0 +1,183 @@
FlexForm
.. include:: /Includes.rst.txt
.. _breadcrumb:
===============
Breadcrumb menu
===============
There are currently two suggested ways to make a breadcrumb menu containing
the detail page of the current news: Based on data processing and Fluid template
and based on pure TypoScript. Use the first method if you have no breadcrumb yet
or your breadcrumb is already based on data processors. Use the second if
your breadcrumb is already based on TypoScript and you do not wish to change it
for now.
.. _breadcrumbFluid:
Breadcrumb based on data processing and Fluid
=============================================
.. versionadded:: 7.2.0
With version 7.2 a new data processor, :php:`AddNewsToMenuProcessor` has
been added which is useful for detail pages to add the news record as
fake menu entry.
To use the data processor :php:`AddNewsToMenuProcessor` add the following
TypoScript to the setup section in your site package extension. We assume
here that your main :typoscript:`FLUIDTEMPLATE` can be found in
:typoscript:`page.10`.
.. code-block:: typoscript
page.10 = FLUIDTEMPLATE
page.10 {
# [...] template settings
dataProcessing {
# [...] Other data processors
50 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
50 {
as = breadcrumbMenu
special = rootline
}
60 = GeorgRinger\News\DataProcessing\AddNewsToMenuProcessor
60.menus = breadcrumbMenu
}
}
The property :typoscript:`menus` of the :php:`AddNewsToMenuProcessor` must
contain the key of the :php:`MenuProcessor` containing your breadcrumb. If you
You can use more then one menu here by supplying several keys as comma-separated
list. For example: :typoscript:`60.menus = breadcrumbMenu,myOtherBreadcrumb`.
The data array containing your breadcrumb will now contain an additional entry
if you are on a news detail page. You can debug this data with the following
Fluid snippet:
.. code-block:: html
<f:debug>{breadcrumbMenu}</f:debug>
The array will then contain something like that:
.. code-block:: none
array(4 items)
0 => array(7 items)
1 => array(7 items)
2 => array(7 items)
data => array(84 items)
title => 'All News' (17 chars)
link => '/portal/news/' (34 chars)
target => '' (0 chars)
active => 1 (integer)
current => 0 (integer)
spacer => 0 (integer)
3 => array(6 items)
data => array(87 items)
title => 'Test news' (13 chars)
active => 1 (integer)
current => 1 (integer)
link => 'https://my-page.ddev.site/portal/news/articel/test-news' (101 chars)
isNews => TRUE
You can use code like the following in your sites Fluid template.
.. code-block:: html
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<f:for each="{breadcrumbMenu}" as="item" iteration="iterator">
<li class="breadcrumb-item ">
<a href="{item.link}" title="{item.title}">
<f:if condition="{item.isNews}"><i class="fas fa-newspaper"></i></f:if>
{item.title}
</a>
</li>
</f:for>
</ol>
</nav>
</div>
The result (using Bootstrap 5 and Fontawesome 5 Free) could use like this:
.. figure:: /Images/Frontend/Breadcrumb.png
:class: with-shadow
A breadcrumb containing the current news record.
.. hint::
I you are displaying the news on a single page that should not be displayed
without a valid news record, unset the flag :guilabel:`Page enabled in menus`
in the single pages page properties. This way the page alone does not appear
in the breadcrumb.
See also chapter :ref:`AddNewsToMenuProcessor <dataProcessing_AddNewsToMenuProcessor>`.
.. _breadcrumbTypoScript:
Breadcrumb based on TypoScript (legacy)
=======================================
If you already have a breadcrumb menu based on TypoScript in your project,
you can continue to use it and add the news record to it.
.. code-block:: typoscript
lib.navigation_breadcrumb = COA
lib.navigation_breadcrumb {
stdWrap.wrap = <ul class="breadcrumb">|</ul>
10 = HMENU
10 {
special = rootline
#special.range = 1
1 = TMENU
1 {
NO = 1
NO {
wrapItemAndSub = <li>|</li>
ATagTitle.field = subtitle // title
stdWrap.htmlSpecialChars = 1
}
CUR <.NO
CUR {
wrapItemAndSub = <li class="active">|</li>
doNotLinkIt = 1
}
}
}
# Add news title if on single view
20 = RECORDS
20 {
stdWrap.if.isTrue.data = GP:tx_news_pi1|news
dontCheckPid = 1
tables = tx_news_domain_model_news
source.data = GP:tx_news_pi1|news
source.intval = 1
conf.tx_news_domain_model_news = TEXT
conf.tx_news_domain_model_news {
field = title
htmlSpecialChars = 1
}
stdWrap.wrap = <li>|</li>
stdWrap.required = 1
}
}
The relevant part starts with :typoscript:`20 = RECORDS` as this cObject
renders the title of the news article.
.. Important::
Never forget the :typoscript:`source.intval = 1` to avoid SQL injections
and the :typoscript:`htmlSpecialChars = 1` to avoid Cross-Site Scripting.
See :ref:`security in TypoScript in TYPO3 Explained
<t3coreapi:security-typoscript>`.

View File

@@ -0,0 +1,115 @@
.. include:: /Includes.rst.txt
.. _cacheClearing:
==============
Cache clearing
==============
.. _cacheClearing-changed-records:
Clearing the cache after changing news records
==============================================
News has a built-in mechanism that takes care of clearing the cache after
manipulation of News records.
When a list or detail view is rendered on a page, a cache tag in format
:php:`tx_news_pid_PID` (where PID is the uid of the news storage folder) is
added. Each time a news record is edited, deleted or created, this cache entry
is flushed. No additional cache configuration is needed if only the News
plugins are used.
If you use other ways of displaying news records (e.g. an RSS feed created
by TypoScript on a page without a News plugin), the cache is not flushed
automatically.
This can be done automatically by using this command in the PageTsConfig: :
.. code-block:: typoscript
:caption: page TSconfig
TCEMAIN.clearCacheCmd = 123,456,789
The code needs to be added to the sys folder where the news records are edited.
Change the example page ids to the ones which should be cleared, e.g. a page
with an RSS feed. You can use:
.. code-block:: typoscript
:caption: page TSconfig
TCEMAIN.clearCacheCmd = pages
to clear the complete caches as well:
.. code-block:: typoscript
:caption: page TSconfig
TCEMAIN.clearCacheCmd = cacheTag:tx_news
to clear all caches of pages on which the news plugins are used but beware of
performance issues when news records are edited often.
.. hint::
The mentioned TCEMAIN settings are part of the TYPO3 Core and can be used
therefore not only for the news extension. Read more about the
:ref:`clearCacheCmd in the TSconfig reference <t3tsconfig:pagetcemain-clearcachecmd>`.
.. _cacheClearing-publishing-date:
Cache lifetime and auto publishing (by setting start date)
==========================================================
By default the cache of TYPO3 pages is invalidated every 24 hours. If you set
a specific date and time for the news record to be published in the tab
:guilabel:`Access`:
.. include:: /Images/ManualScreenshots/NewsRecordAccess.rst.txt
The news will be published next time the cache is deleted which is usual after
midnight.
When you are using the :guilabel:`Publish Date` field you can use the following
TypoScript setup configuration: :ref:`config.cache <t3tsref:setup-config-cache>`
Let us assume you have a news plugin on page 42 and store your news records in a
sysfolder with the uid 27 then the following setting will take the publish date
of your news records into account when calculating the time when the cache
should expire:
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/TypoScript/setup.typoscript
config.cache.42 = tx_news_domain_model_news:27
If there is more then one page containing a news plugin that might display the
news you have to make a setting for each page:
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/TypoScript/setup.typoscript
config.cache {
42 = tx_news_domain_model_news:27
43 = tx_news_domain_model_news:27
365 = tx_news_domain_model_news:27
}
If you use a news plugin on every page it is also possible to define the
cache clearing for all pages:
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/TypoScript/setup.typoscript
config.cache.all = tx_news_domain_model_news:27
You can also define serveral tables for one page, for example to include
categories:
.. code-block:: typoscript
:caption: EXT:my_sitepackage/Configuration/TypoScript/setup.typoscript
config.cache.42 = tx_news_domain_model_news:27,sys_category:26

View File

@@ -0,0 +1,72 @@
.. include:: /Includes.rst.txt
.. _hideDetailPage:
=======================
Hide detail page in URL
=======================
This tutorials covers the use case of having the following page structure:
.. code-block:: none
.
└── Root
├── Home
└── Blog <= news
The URL of a news record should howeverb be `domain.tld/blog/news-record`.
The page *Blog* typically contains not only the news plugin with the list view
but also additional regular content elements which must **not** be rendered in the detail view.
The following TypoScript will make this possible:
.. code-block:: typoscript
# Override content rendering if the news record is requested
[traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]
# typically having something like: page.10 = FLUIDTEMPLATE
# optional to use a custom page template
page.10.templateName = NewsDetail
lib.dynamicContent >
lib.dynamicContent = USER
lib.dynamicContent {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
switchableControllerActions {
News {
1 = detail
}
}
settings < plugin.tx_news.settings
settings {
# fully optional but can be used to react on it in
# the news templates
templateLayout = renderedByTs
}
}
[end]
The **page template** `NewsDetail.html` must contain the following code to
render the news detail view:
.. code-block:: html
<f:cObject typoscriptObjectPath="lib.dynamicContent" />
Some further explanations
^^^^^^^^^^^^^^^^^^^^^^^^^
* The TypoScript condition will only be true if a news record path is in the URL
* It overrides the used page template to be able to use a custom one
* It set the variable `lib.dynamicContent` to contain the rendered news detail view
* The dedicated page template can be fully adopted
* If needed, the News detail template can be adopted by either use a settings variable or by providing a custom view path.

View File

@@ -0,0 +1,206 @@
.. include:: /Includes.rst.txt
.. _icalendar:
==============
ICalendar feed
==============
Displaying an iCalendar feed is the same as a normal list view, just with a different template.
Therefore you won't need any different configuration to e.g. excluded categories or configure the single view page.
.. only:: html
.. contents::
:local:
:depth: 3
The template for the iCalendar feed can be found in the file Resources/Private/Templates/News/List.ical.
The "magic" which uses the List.ical template instead of the List.html is the following configuration:
.. code-block:: typoscript
plugin.tx_news.settings.format = ical
plugin.tx_news.settings.domain.data = getEnv:HTTP_HOST
plugin.tx_news.settings.useStdWrap = domain
iCalendar feed by TypoScript
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A very simple way to generate the iCalendar feed is using plain TypoScript. All you need is to use the given TypoScript and adopt it to your needs.
.. code-block:: typoscript
[globalVar = TSFE:type = 9819]
config {
disableAllHeaderCode = 1
xhtml_cleaning = none
admPanel = 0
metaCharset = utf-8
# For 7 LTS
additionalHeaders = Content-Type:text/calendar;charset=utf-8
# Since 8 LTS
additionalHeaders.10.header = Content-Type:text/calendar;charset=utf-8
disablePrefixComment = 1
linkVars >
}
pageNewsICalendar = PAGE
pageNewsICalendar {
typeNum = 9819
10 < tt_content.list.20.news_pi1
10 {
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
categories = 9
categoryConjunction = notor
limit = 30
detailPid = 25
startingpoint = 24
format = ical
domain.data = getEnv:HTTP_HOST
useStdWrap = domain
}
}
}
[global]
This example will show all news records which don't have the category with the uid 9 assigned and are saved on the page with uid 24.
The iCalendar feed itself can be found with the link **/?type=9819**.
iCalendar feeds by using a normal plugin
""""""""""""""""""""""""""""""""""""""""
Sometimes it is more convenient to generate the iCalendar feed using the normal plugin.
The biggest advantage is that the complete configuration can be done within the backend without touching TypoScript.
To create an ICalendar feed based on a plugin follow this steps:
#. Create a new page.
#. Add the news plugin and define the configuration you need. E.g. startingpoint, page with the single view, ...
#. Define a new TypoScript template and use a code like below. **Very
important** : Use :typoscript:`config.absRefPrefix = http://www.yourdomain.tld/` to
produce absolute urls for links and images!
.. code-block:: typoscript
page = PAGE
page.10 < styles.content.get
page.config {
# deactivate Standard-Header
disableAllHeaderCode = 1
# no xhtml tags
xhtml_cleaning = none
admPanel = 0
metaCharset = utf-8
# define charset
additionalHeaders = Content-Type:text/calendar;charset=utf-8
disablePrefixComment = 1
linkVars >
}
# set the format
plugin.tx_news.settings.format = ical
# set the domain for real unique uids
plugin.tx_news.settings.domain.data = getEnv:HTTP_HOST
plugin.tx_news.settings.useStdWrap = domain
# delete content wrap
tt_content.stdWrap >
**Important:** If your output still contains HTML code, please check your TypoScript
(especially from css\_styled\_content) as this HTML is produced there!
Automatic iCalendar feeds - based on plugins
""""""""""""""""""""""""""""""""""""""""""""
There are use cases where many different list views are needed and each list view should also get its own iCalendar feed **without any additional configuration**.
The TypoScript code looks like this.
.. code-block:: typoscript
[globalVar = TSFE:type = 9819]
lib.stdheader >
tt_content.stdWrap.innerWrap >
tt_content.stdWrap.wrap >
# get away <div class="feEditAdvanced-firstWrapper" ...> if your logged into the backend
styles.content.get.stdWrap >
pageNewsICalendar = PAGE
pageNewsICalendar.typeNum = 9819
pageNewsICalendar.10 < styles.content.get
pageNewsICalendar.10.select.where = colPos=0 AND list_type = "news_pi1"
pageNewsICalendar.10.select {
orderBy = sorting ASC
max = 1
}
config {
# deactivate Standard-Header
disableAllHeaderCode = 1
# no xhtml tags
xhtml_cleaning = none
admPanel = 0
metaCharset = utf-8
# you need an english locale to get correct rfc values for <lastBuildDate>, ...
locale_all = en_EN
# define charset
additionalHeaders = Content-Type:text/calendar;charset=utf-8
disablePrefixComment = 1
linkVars >
}
# set the format
plugin.tx_news.settings.format = ical
# set the domain for real unique uids
plugin.tx_news.settings.domain.data = getEnv:HTTP_HOST
plugin.tx_news.settings.useStdWrap = domain
# delete content wrap
tt_content.stdWrap >
[global]
**Some explanations**
The page object ``pageNewsICalendar`` will render only those content elements which are in colPos 0 and are a news plugin. Therefore all other content elements won't be rendered in the iCalendar feed.
Misc
^^^^
Add a link to the iCalendar feed in the list view
"""""""""""""""""""""""""""""""""""""""""""""""""
To be able to render a link in the header section of the normal page which points to the iCalendar feed you can use something like this in your List.html Fluid template.
.. code-block:: html
<n:headerData>
<link rel="alternate" type="text/calendar" title="iCalendar 2.0" href="{f:uri.page(additionalParams:{type:9819})}" />
</n:headerData>
Change the iCalendar feed link with routing
"""""""""""""""""""""""""""""""""""""""""""
If you want to rewrite the URL, use a configuration like this one. Read more
about :ref:`rewriting URLs for news <routing>`.
.. code-block:: yaml
routeEnhancers:
News:
PageTypeSuffix:
type: PageType
map:
'feed.xml': 9818
'calendar.ical': 9819
This will change the URL to :code:`/calendar.ical`.

View File

@@ -0,0 +1,188 @@
.. include:: /Includes.rst.txt
.. _tutorialsBestPractice:
=============
Best practice
=============
.. container:: row m-0 p-0
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`SEO <seo>`
.. container:: card-body
Optimize EXT:news for display in search engines.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`View Button <viewButton>`
.. container:: card-body
Display a :guilabel:`View` button on top of news records in the
backend.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`TSconfig code snippets <general_tsconfig_examples>`
.. container:: card-body
Code snippets to influence the behaviour of news record editing
in the backend and the news administration module.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Routing <routing>`
.. container:: card-body
Use routing to generate user readable urls to news, categories,
tags, paginized results etc
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Breadcrumb menu <breadcrumb>`
.. container:: card-body
Display the current news title in the breadcrumb
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`RSS <rss>`
.. container:: card-body
Provide a RSS feed promoting your news
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`ICalendar feed <icalendar>`
.. container:: card-body
Provide an iCalendar feed
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`LinkHandler <linkhandler>`
.. container:: card-body
Enable your editors to link to specific news from anywhere.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Limit content elements <limitCE>`
.. container:: card-body
Configure available content element types in news records.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Integrations with TypoScript <integrationTypoScript>`
.. container:: card-body
Configure available content element types in news records.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Cache clearing <cacheClearing>`
.. container:: card-body
Automatic cache clearing
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Predefine values <predefineValues>`
.. container:: card-body
Learn how to set default values, influence the choices of select
fields etc.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Hide detail page <hideDetailPage>`
.. container:: card-body
Avoid the detail page in the url and reuse the list page.
.. toctree::
:maxdepth: 5
:titlesonly:
:hidden:
Seo/Index
PreviewOfRecord/Index
TsConfigExamples/Index
Routing/Index
BreadcrumbMenu
Rss/Index
Linkhandler/Index
AvailableContentElements/Index
IntegrationWithTypoScript/Index
HideDetailPage/Index
ClearCache/Index
PredefineFields/Index
ICalendar/Index

View File

@@ -0,0 +1,325 @@
.. include:: /Includes.rst.txt
.. highlight:: typoscript
.. _integrationTypoScript:
============================
Integrations with TypoScript
============================
This page gives you same examples which you can use for integrating EXT:news into a website.
.. only:: html
.. contents::
:local:
:depth: 1
Add news by TypoScript
^^^^^^^^^^^^^^^^^^^^^^
If EXT:news should be integrated by using TypoScript only, you can use this code snippet:
.. code-block:: typoscript
lib.news = USER
lib.news {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
//categories = 49
limit = 30
detailPid = 31
overrideFlexformSettingsIfEmpty := addToList(detailPid)
startingpoint = 13
}
}
Now you can use the object lib.news.
List and detail on the same page using TypoScript
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the example of how to display list and detail view on the same page.
.. code-block:: typoscript
# Basic plugin settings
lib.news = USER
lib.news {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
pluginName = Pi1
vendorName = GeorgRinger
extensionName = News
controller = News
settings =< plugin.tx_news.settings
persistence =< plugin.tx_news.persistence
view =< plugin.tx_news.view
}
Configure list and detail actions:
.. code-block:: typoscript
lib.news_list < lib.news
lib.news_list {
action = list
switchableControllerActions.News.1 = list
}
lib.news_detail < lib.news
lib.news_detail {
action = detail
switchableControllerActions.News.1 = detail
}
Insert configured objects to wherever you want to use them, depending on the GET parameter of detail view:
.. code-block:: typoscript
[traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]
page.10.marks.content < lib.news_detail
[else]
page.10.marks.content < lib.news_list
[end]
Add news to breadcrumb menu
^^^^^^^^^^^^^^^^^^^^^^^^^^^
This example has been moved to the
:ref:`Tutorial: Breadcrumb menus <breadcrumbTypoScript>`.
Add HTML to the header part in the detail view.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There might be a use case where you need to add specific code to the header part when the detail view is rendered.
There are some possible ways to go.
Plain TypoScript
""""""""""""""""
You could use a code like the following one to render e.g. the title of a news article inside a title-tag.
.. code-block:: typoscript
[globalVar = TSFE:id = NEWS-DETAIL-PAGE-ID]
config.noPageTitle = 2
temp.newsTitle = RECORDS
temp.newsTitle {
dontCheckPid = 1
tables = tx_news_domain_model_news
source.data = GP:tx_news_pi1|news
source.intval = 1
conf.tx_news_domain_model_news = TEXT
conf.tx_news_domain_model_news {
field = title
htmlSpecialChars = 1
}
wrap = <title>|</title>
}
page.headerData.1 >
page.headerData.1 < temp.newsTitle
[global]
If you want to show the categories of a news record, you can use the following code:
.. code-block:: typoscript
lib.categoryTitle = CONTENT
lib.categoryTitle {
if.isTrue.data = GP:tx_news_pi1|news
table = tx_news_domain_model_news
select {
uidInList.data = GP:tx_news_pi1|news
pidInList = 123
join = sys_category_record_mm ON tx_news_domain_model_news.uid = sys_category_record_mm.uid_foreign JOIN sys_category ON sys_category.uid = sys_category_record_mm.uid_local
orderBy = sys_category.sorting
max = 1
}
renderObj = TEXT
renderObj {
field = title
htmlSpecialChars = 1
}
}
Usage of a ViewHelper
"""""""""""""""""""""
Use a viewHelper of EXT:news to write any code into the header part. The code could look like this
.. code-block:: xml
<n:headerData><script>var newsId = {newsItem.uid};</n:headerData>
If you want to set the title tag, you can use a specific viewHelper:
.. code-block:: xml
<n:titleTag>{newsItem.title}</n:titleTag>
Fallback in Detail view if no news found
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the detail view is called without a news uid given, an error is thrown (depending on the setting **settings.errorHandling**).
If the desired behaviour is to show a different news record this can be set in the plugin with the field "singleNews".
The drawback would be that the alternative news record would be always the same. If this should be kind of dynamic, take a
look at the given TypoScript snippet:
.. code-block:: typoscript
plugin.tx_news.settings {
overrideFlexformSettingsIfEmpty = singleNews,cropMaxCharacters,dateField,timeRestriction,orderBy,orderDirection,backPid,listPid,startingpoint
useStdWrap = singleNews
singleNews.stdWrap.cObject = CONTENT
singleNews.stdWrap.cObject {
table = tx_news_domain_model_news
select {
max = 1
orderBy = datetime desc
pidInList = 3
}
renderObj = TEXT
renderObj.field = uid
}
}
By using the field *useStdWrap* it is possible to call the full range of stdWrap on any setting. In this case the first news record
from the page with uid 3 is used as fallback.
Show news items with same category in Detail.html
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to show in the detail action articles with the same category as the current one, you can use a snippet like this one:
Add this to the ``Detail.html`` which will pass the first category uid to the TypoScript object ``lib.tx_news.relatedByFirstCategory``.
.. code-block:: html
<f:if condition="{newsItem.firstCategory}">
<f:cObject typoscriptObjectPath="lib.tx_news.relatedByFirstCategory">{newsItem.firstCategory.uid}</f:cObject>
</f:if>
.. code-block:: typoscript
lib.tx_news.relatedByFirstCategory = USER
lib.tx_news.relatedByFirstCategory {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
relatedView = 1
detailPid = 31
useStdWrap := addToList(categories)
categories.current = 1
categoryConjunction = or
overrideFlexformSettingsIfEmpty := addToList(detailPid)
startingpoint = 78
}
}
Important is the line ``categories.current = 1`` which will set the category configuration.
Of course you need to adopt the snippet to your own needs, like setting the ``detailPid``, ``startingPoint``, ...
By defining a custom property like ``relatedView = 1`` you can differ in the ``List.html`` if it is called by this snippet or by a regular plugin.
Show news items with same tags in Detail.html
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Similar to the example above it is also possible to render news records with the same tags as the current one.
.. code-block:: typoscript
lib.tx_news.relatedByTags = USER
lib.tx_news.relatedByTags {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
# custom tag to use in List.html
relatedView = 1
# limit number of news
limit = 6
# startingpoint = 1
useStdWrap := addToList(tags)
tags.current = 1
categoryConjunction = or
overrideFlexformSettingsIfEmpty := addToList(detailPid)
excludeAlreadyDisplayedNews = 1
}
}
In your overridden Detail.html template place the following code after displaying detailed news.
.. code-block:: html
<f:if condition="{newsItem.tags}">
<f:cObject typoscriptObjectPath="lib.tx_news.relatedByTags">{newsItem.tags->v:iterator.extract(key:'uid')->v:iterator.implode(glue: ',')}</f:cObject>
</f:if>
The Fluid tags supply comma-separated list of tags' UIDs to the Typoscript code.
Either write custom ViewHelper or install vhs extension and add its namespace :html:`xmlns:v="http://typo3.org/ns/FluidTYPO3/Vhs/ViewHelpers"` to the `Detail.html` template.
Show Category Menu with Typoscript
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. code-block:: typoscript
lib.categoryMenu = USER
lib.categoryMenu {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
extensionName = News
pluginName = Pi1
vendorName = GeorgRinger
action = category
switchableControllerActions {
Category {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
listPid = 11
}
}

View File

@@ -0,0 +1,77 @@
.. include:: /Includes.rst.txt
.. _linkhandler:
===========
LinkHandler
===========
**LinkHandler** is the synonym for making it possible for editors to create links to custom records.
Until 8 LTS a 3rd party extension has been required but since then it is integrated into the Core. Read at https://docs.typo3.org/typo3cms/extensions/core/8.7/Changelog/8.6/Feature-79626-IntegrateRecordLinkHandler.html about the feature.
.. tip::
This tutorial is also valid for creating links to any other record.
Configuration for the backend
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PageTsConfig is used to configure the link browser in the backend.
.. code-block:: typoscript
# tx_news is an identifier, don't change it after links have been created
TCEMAIN.linkHandler.tx_news {
handler = TYPO3\CMS\Recordlist\LinkHandler\RecordLinkHandler
# A translatable label can be used with LLL:EXT:theme/locallang.xml:label
label = News
configuration {
table = tx_news_domain_model_news
# Default storage pid
storagePid = 123
# Hide the page tree by setting it to 1
hidePageTree = 0
}
scanAfter = page
}
Configuration for the frontend
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The links are now stored in the database with the syntax `<a href="t3://record?identifier=tx_news&amp;uid=456">A link</a>`.
By using TypoScript, the link is transformed into an actual link.
.. code-block:: typoscript
config.recordLinks.tx_news {
typolink {
# Detail page
parameter = 123
additionalParams.data = field:uid
additionalParams.wrap = &tx_news_pi1[controller]=News&tx_news_pi1[action]=detail&tx_news_pi1[news]=|
}
}
Dynamic target page from category field single_pid
""""""""""""""""""""""""""""""""""""""""""""""""""
if the detail page is provided by the category, the following code can be used to retrieve the target page:
.. code-block:: typoscript
config.recordLinks.tx_news {
typolink {
# Detail page
parameter.cObject = USER
parameter.cObject {
userFunc = GeorgRinger\News\Service\LinkHandlerTargetPageService->process
news.data = field:uid
# Page used if no detail page is set in the category
fallback = 123
}
additionalParams.data = field:uid
additionalParams.wrap = &tx_news_pi1[controller]=News&tx_news_pi1[action]=detail&tx_news_pi1[news]=|
}
}

View File

@@ -0,0 +1,111 @@
.. include:: /Includes.rst.txt
.. _predefineValues:
================
Predefine values
================
This section will show you how you can predefine values of fields in records in the TYPO3 backend using TSconfig.
Default values
^^^^^^^^^^^^^^
.. tip:: This is a feature of TYPO3 itself, so you can use this also for all other tables and fields.
If you want to use some default values, you can use this code inside the TSconfig (tab:Resources) of the folder containing the News records:
.. code-block:: typoscript
# Syntax is always TCAdefaults.<tablename>.<fieldname> = value
TCAdefaults {
tx_news_domain_model_news {
author = John Doe
categories = 9
}
}
Select fields
^^^^^^^^^^^^^
If you want to preselect a value from a select field, you need to set the value of the option field as value.
In this example the language with the uid 3 will be preselected:
.. code-block:: typoscript
TCAdefaults.tx_news_domain_model_news {
sys_language_uid = 3
}
If you want to remove an option from a select field you can take a look at this example which removes the
option "Images" from the media selection dropdown:
.. code-block:: typoscript
TCEFORM.tx_news_domain_model_media {
type.removeItems = 0
}
Author name & email
^^^^^^^^^^^^^^^^^^^
By using the following code in the PageTsConig, the fields `Author` and `Author Email` are prefilled with the name and email address of the current backend user
.. code-block:: typoscript
tx_news.predefine.author = 1
Archive date
^^^^^^^^^^^^
EXT:news allows you to use an improved syntax to predefine the archive date by using this Page TSconfig:
.. code-block:: typoscript
tx_news.predefine.archive = <value>
As value you can use anything which can be interpreted by the php function `strtotime <http://de2.php.net/manual/en/function.strtotime.php>`__.
For example:
- +1 day
- next Monday
- +1 week 2 days 4 hours
Add the characters counter below an input field
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you want to give a hint to editors so they know how many chars they can use for the Teaser field, you simply add this TSconfig to the folder:
.. code-block:: typoscript
TCEFORM.tx_news_domain_model_news.teaser.config.max = 200
Modify flexform values
^^^^^^^^^^^^^^^^^^^^^^
The flexform values can be modified by using TSconfig.
.. code-block:: typoscript
TCEFORM {
tt_content {
pi_flexform {
news_pi1 {
sDEF {
settings\.orderDirection.disabled = 1
settings\.orderBy.addItems {
teaser = teaser
}
}
}
}
}
}
.. attention::
The dot inside the field name must be escaped!
To identify the key of the tab (e.g. `sDEF`) and the field name (e.g. `settings.orderBy`)
look either in the source code while checking the flexforms or look into the configuration itself
which can be found at `EXT:news/Configuration/FlexForms/flexform_news.xml`.

View File

@@ -0,0 +1,47 @@
.. include:: /Includes.rst.txt
.. _viewButton:
===========
View button
===========
It is possible to activate the :guilabel:`View` Button for news records.
This button is displayed on the top of the edit record page:
.. figure:: /Images/ManualScreenshots/ViewButton.png
:class: with-shadow
The :guilabel:`View` button
Add the following page TSconfig to your root page. It is recommended to use
a site package extension, see
:doc:`Official Tutorial: Site Package <t3sitepackage:Index>` for this purpose.
.. code-block:: typoscript
TCEMAIN.preview {
tx_news_domain_model_news {
previewPageId = 123
useDefaultLanguageRecord = 0
fieldToParameterMap {
uid = tx_news_pi1[news_preview]
}
additionalGetParameters {
tx_news_pi1.controller = News
tx_news_pi1.action = detail
}
}
}
By using the given example, a link will be generated which leads to the
page with the id `123`.
If a news plugin is placed on this page, the news article will be shown.
.. hint::
This TSconfig configuration can be used to display any record with with any
kind of parameters. Read more about it in
:ref:`TSconfig Reference: TCEMAIN.preview <t3tsconfig:pagetcemain-preview>`.

View File

@@ -0,0 +1,16 @@
:orphan:
.. TODO: remove this section with the next major release of news
.. include:: /Includes.rst.txt
.. _realurl:
============================
Replace RealURL with routing
============================
The extension EXT:realurl is outdated. Use the build-in
:ref:`TYPO3 routing <routing>` to rewrite the urls instead. Read more about
:ref:`Migration from realurl to news with routing <migration_realurl_routing>`.

View File

@@ -0,0 +1,475 @@
.. include:: /Includes.rst.txt
.. _routing:
===========================
Use Routing to rewrite URLs
===========================
This section will show you how you can rewrite the URLs for news using
**Routing Enhancers and Aspects**. TYPO3 Explained has an capter
:ref:`Introduction to routing <t3coreapi:routing-introduction>` that you can read
if you are not familiar with the concept yet. You will no
longer need third party extensions like RealURL or CoolUri to rewrite and
beautify your URLs.
.. _how_to_rewrite_urls:
How to rewrite URLs with news parameters
----------------------------------------
On setting up your page you should already have created a **site configuration**.
You can do this in the backend module :guilabel:`Site Managements > Sites`.
Your site configuration will be stored in
:file:`/config/sites/<your_identifier>/config.yaml`. The following
configurations have to be applied to this file.
Any URL parameters can be rewritten with the Routing Enhancers and Aspects.
These are added manually in the :file:`config.yaml`:
#. Add a section :yaml:`routeEnhancers`, if one does not already exist.
#. Choose an unique identifier for your Routing Enhancer. It doesn't have
to match any extension key.
#. :yaml:`type`: For news, the Extbase Plugin Enhancer (:yaml:`Extbase`)
is used.
#. :yaml:`extension`: the extension key, converted to :code:`UpperCamelCase`.
#. :yaml:`plugin`: the plugin name of news is just *Pi1*.
#. After that you will configure individual routes and aspects depending on
your use case.
.. code-block:: yaml
:linenos:
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
routeEnhancers:
News:
type: Extbase
extension: News
plugin: Pi1
# routes and aspects will follow here
.. tip::
If your routing doesn't work as expected, check the **indentation** of your
configuration blocks.
Proper indentation is crucial in YAML.
Using limitToPages
~~~~~~~~~~~~~~~~~~
It is recommended to limit :yaml:`routeEnhancers` to the pages where they are needed.
This will speed up performance for building page routes of all other pages.
.. code-block:: yaml
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
:linenos:
:emphasize-lines: 4-7
routeEnhancers:
News:
type: Extbase
limitToPages:
- 8
- 10
- 11
extension: News
plugin: Pi1
# routes and aspects will follow here
Multiple routeEnhancers for news
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you use the news extension for different purposes on the same website
(for example news and events), you may want different URL paths for
them (for example */article/* and */event/*).
It is possible to configure more than one routing enhancer for the news plugin
on the same website.
Use :yaml:`limitToPages` to assign the appropriate configuration to the
desired pages.
.. code-block:: yaml
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
:linenos:
:emphasize-lines: 2,11
routeEnhancers:
News:
type: Extbase
limitToPages:
- 8
- 10
- 11
extension: News
plugin: Pi1
# etc.
NewsEvents:
type: Extbase
limitToPages:
- 17
- 18
extension: News
plugin: Pi1
# etc.
About routes and aspects
~~~~~~~~~~~~~~~~~~~~~~~~
In a nutshell:
* :yaml:`routes` will extend an existing route (means: your domain and page
path) with arguments from GET parameters, like the following
controller/action pair of the news detail view.
* :yaml:`aspects` can be used to modify these arguments. You could for
example map the title (or better: the optimized path segment) of the
current news.
Different types of *Mappers* and *Modifiers* are available, depending on
the case.
1. URL of detail page without routing:
.. code-block:: none
https://www.example.com/news/detail?tx_news_pi1[action]=detail&tx_news_pi1[controller]=News&tx_news_pi1[news]=5&cHash=
2. URL of detail page with routes:
.. code-block:: none
https://www.example.com/news/detail/5?cHash=
3. URL of detail page with routes and aspects:
.. code-block:: none
https://www.example.com/news/detail/title-of-news-article
The following example will only provide routing for the detail view:
.. code-block:: yaml
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
:linenos:
routeEnhancers:
News:
type: Extbase
extension: News
plugin: Pi1
routes:
- routePath: '/{news-title}'
_controller: 'News::detail'
_arguments:
news-title: news
aspects:
news-title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
Please note the placeholder :code:`{news-title}`:
#. First, you assign the value of the news parameter (:code:`tx_news_pi1[news]`)
in :yaml:`_arguments`.
#. Next, in :yaml:`routePath` you add it to the existing route.
#. Last, you use :yaml:`aspects` to map the :code:`path_segment` of the
given argument.
Both routes and aspects are only available within the current Routing Enhancer.
The names of placeholders are freely selectable.
Common routeEnhancer configurations
-----------------------------------
Basic setup (including categories, tags and the RSS/Atom feed)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Prerequisites:**
The plugins for :guilabel:`List View` and :guilabel:`Detail View` are on
separate pages.
If you use the :guilabel:`Category Menu` or :guilabel:`Tag List` plugins to
filter news records, their titles (slugs) are used.
**Result:**
* Detail view: ``https://www.example.com/news/detail/the-news-title``
* Pagination: ``https://www.example.com/news/page-2``
* Category filter: ``https://www.example.com/news/my-category``
* Tag filter: ``https://www.example.com/news/my-tag``
.. code-block:: yaml
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
:linenos:
routeEnhancers:
News:
type: Extbase
extension: News
plugin: Pi1
routes:
- routePath: '/'
_controller: 'News::list'
- routePath: '/page-{page}'
_controller: 'News::list'
_arguments:
page: '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
PageTypeSuffix:
type: PageType
map:
'feed.xml': 9818
'calendar.ical': 9819
Localized pagination
~~~~~~~~~~~~~~~~~~~~
**Prerequisites:**
The website provides several frontend languages.
**Result:**
* English: ``https://www.example.com/news/page-2``
* Danish: ``https://www.example.com/da/news/side-2``
* German: ``https://www.example.com/de/news/seite-2``
.. code-block:: yaml
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
:linenos:
:emphasize-lines: 21-27
routeEnhancers:
News:
type: Extbase
extension: News
plugin: Pi1
routes:
- routePath: '/{page-label}-{page}'
_controller: 'News::list'
_arguments: {'page': 'currentPage'}
defaultController: 'News::list'
defaults:
page: ''
requirements:
page: '\d+'
aspects:
page:
type: StaticRangeMapper
start: '1'
end: '100'
page-label:
type: LocaleModifier
default: 'page'
localeMap:
- locale: 'da_DK.*'
value: 'side'
- locale: 'de_DE.*'
value: 'seite'
**Explanation:**
The :yaml:`LocaleModifier` aspect type will set a default value for the
English language.
You're then able to add as many :yaml:`localeMap` configurations as you
need for the page translations of your website.
The value of :yaml:`locale` refers to the value in your site configuration.
Human readable dates
~~~~~~~~~~~~~~~~~~~~
**Prerequisites:**
For :guilabel:`List View` with a :guilabel:`Date Menu` plugin, to filter
by date. Also includes configuration for the pagination.
**Result:**
* ``https://www.example.com/news/2018/march``
* ``https://www.example.com/news/2018/march/page-2``
.. code-block:: yaml
:caption: :file:`/config/sites/<your_identifier>/config.yaml`
:linenos:
routeEnhancers:
DateMenu:
type: Extbase
extension: News
plugin: Pi1
routes:
# Pagination:
- routePath: '/'
_controller: 'News::list'
- routePath: '/page-{page}'
_controller: 'News::list'
_arguments:
page: 'currentPage'
requirements:
page: '\d+'
- routePath: '/{news-title}'
_controller: 'News::detail'
_arguments:
news-title: news
# Date year:
- routePath: '/{date-year}'
_controller: 'News::list'
_arguments:
date-month: 'overwriteDemand/month'
date-year: 'overwriteDemand/year'
page: 'currentPage'
requirements:
date-year: '\d+'
# Date year + pagination:
- routePath: '/{date-year}/page-{page}'
_controller: 'News::list'
_arguments:
date-year: 'overwriteDemand/year'
page: 'currentPage'
requirements:
date-year: '\d+'
page: '\d+'
# Date year/month:
- routePath: '/{date-year}/{date-month}'
_controller: 'News::list'
_arguments:
date-month: 'overwriteDemand/month'
date-year: 'overwriteDemand/year'
page: 'currentPage'
requirements:
date-month: '\d+'
date-year: '\d+'
# Date year/month + pagination:
- routePath: '/{date-year}/{date-month}/page-{page}'
_controller: 'News::list'
_arguments:
date-month: 'overwriteDemand/month'
date-year: 'overwriteDemand/year'
page: 'currentPage'
requirements:
date-month: '\d+'
date-year: '\d+'
page: '\d+'
defaultController: 'News::list'
defaults:
page: '0'
date-month: ''
date-year: ''
aspects:
news-title:
type: PersistedAliasMapper
tableName: tx_news_domain_model_news
routeFieldName: path_segment
page:
type: StaticRangeMapper
start: '1'
end: '25'
date-month:
type: StaticValueMapper
map:
january: '01'
february: '02'
march: '03'
april: '04'
may: '05'
june: '06'
july: '07'
august: '08'
september: '09'
october: '10'
november: '11'
december: '12'
date-year:
type: StaticRangeMapper
start: '2000'
end: '2030'
**Explanation:**
You will need a new :yaml:`routePath` for every possible combination of
arguments (pagination, month with/without pagination, ...).
**Potential errors:**
If you want :code:`2018/march` but get :code:`2018/3` instead, compare your
:yaml:`StaticValueMapper` for months with your date arguments.
Are you using different date formats (with/without leading zeros)?
You can either remove the leading zero in your :yaml:`aspects` or adapt the
TypoScript setting:
.. code-block:: typoscript
:caption: TypoScript setup
:linenos:
:emphasize-lines: 6
plugin.tx_news.settings.link {
hrDate = 1
hrDate {
day = j
// 'n' for 1 through 12. 'm' for 01 through 12.
month = m
year = Y
}
}
You can configure each argument (day/month/year) separately by using the
configuration of PHP function `date <http://www.php.net/date>`__.
.. warning::
| **Oops, an error occurred!**
| Possible range of all mappers is larger than 10000 items
Using the :yaml:`StaticRangeMapper` is strictly limited to 1000 items per
a single range and 10000 items per routing enhancer.
That means you'll have to multiply all possible combinations in a routing
enhancer, for example:
12 months × 30 years *(2000-2030)* × 25 pages *(pagination)* = 9000 possible
items
If you exceed this limit, you'll either have to build a custom and more
specific mapper, or reduce the range in one of your :yaml:`StaticRangeMapper`.
References
----------
* :ref:`TYPO3 Documentation: Routing <t3coreapi:routing-introduction>`
* :ref:`TYPO3 Documentation: Site Handling <t3coreapi:sitehandling>`
* `TYPO3 CMS Core Changelog 9.5: Feature: #86365 - Routing Enhancers and Aspects <https://docs.typo3.org/typo3cms/extensions/core/Changelog/9.5/Feature-86365-RoutingEnhancersAndAspects.html>`__
* `TYPO3 CMS Core Changelog 9.5: Feature: #86160 - PageTypeEnhancer for mapping &type parameter <https://docs.typo3.org/typo3cms/extensions/core/Changelog/9.5/Feature-86160-PageTypeEnhancerForMappingTypeParameter.html>`__

View File

@@ -0,0 +1,228 @@
.. include:: /Includes.rst.txt
.. _rss:
========
RSS feed
========
Displaying a RSS feed is the same as a normal list view, just with a different template.
Therefore you won't need any different configuration to e.g. excluded categories or configure the single view page.
.. only:: html
.. contents::
:local:
:depth: 3
The template for the RSS feed can be found in the file Resources/Private/Templates/News/List.xml.
The "magic" which uses the List.xml template instead of the List.html is the following configuration:
.. code-block:: typoscript
plugin.tx_news.settings.format = xml
# If you want atom, use
plugin.tx_news.settings.format = atom
RSS feed by TypoScript
^^^^^^^^^^^^^^^^^^^^^^
A very simple way to generate the RSS feed is using plain TypoScript. All you need is to use the given TypoScript and adopt it to your needs.
.. code-block:: typoscript
pageNewsRSS = PAGE
pageNewsRSS {
# Override the typeNum if you have more than one feed
typeNum = {$plugin.tx_news.rss.channel.typeNum}
config {
disableAllHeaderCode = 1
xhtml_cleaning = none
admPanel = 0
debug = 0
disablePrefixComment = 1
metaCharset = utf-8
additionalHeaders.10.header = Content-Type:application/rss+xml;charset=utf-8
absRefPrefix = {$plugin.tx_news.rss.channel.link}
linkVars >
}
10 < tt_content.list.20.news_pi1
10 {
switchableControllerActions {
News {
1 = list
}
}
settings < plugin.tx_news.settings
settings {
categories = 9
categoryConjunction = notor
limit = 30
detailPid = 25
startingpoint = 24
format = xml
# Override the typeNum if you have more than one feed, must be the same as above!
#list.rss.channel.typeNum = {$plugin.tx_news.rss.channel.typeNum}
}
}
}
This example will show all news records which don't have the category with the uid 9 assigned and are saved on the page with uid 24. The single view page is the one with uid 25.
The RSS feed itself can be found with the link :code:`/?type=9818`.
RSS feeds by using a normal plugin
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Sometimes it is more convenient to generate the RSS feed using the normal plugin.
The biggest advantage is that the complete configuration can be done within the backend without touching TypoScript.
To create a RSS feed based on a plugin follow this steps:
#. Create a new page.
#. Add the news plugin and define the configuration you need. E.g. startingpoint, page with the single view, ...
#. Define a new TypoScript template and use a code like below. **Very
important**: Use :typoscript:`config.absRefPrefix = http://www.yourdomain.tld/` to
produce absolute urls for links and images!
.. code-block:: typoscript
page = PAGE
page.10 < styles.content.get
config {
# deactivate Standard-Header
disableAllHeaderCode = 1
# no xhtml tags
xhtml_cleaning = none
admPanel = 0
# define charset
metaCharset = utf-8
additionalHeaders.10.header = Content-Type:application/rss+xml;charset=utf-8
disablePrefixComment = 1
linkVars >
}
# set the format
plugin.tx_news.settings.format = xml
# delete content wrap
tt_content.stdWrap >
tt_content.stdWrap.editPanel = 0
# Use custom template for List.html of EXT:fluid_styled_content
lib.contentElement.templateRootPaths.5 = EXT:news/Resources/Private/Examples/Rss/fluid_styled_content/Templates
.. warning::
If your output still contains HTML code, please check your TypoScript (especially fluid\_styled\_content) as this HTML is produced there!
Automatic RSS feeds - based on plugins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are usecases where many different list views are needed and each list view should also get its own RSS feed **without any additional configuration**.
The TypoScript code looks like this.
.. code-block:: typoscript
[globalVar = TSFE:type = {$plugin.tx_news.rss.channel.typeNum}]
lib.stdheader >
tt_content.stdWrap.innerWrap >
tt_content.stdWrap.wrap >
tt_content.stdWrap.editPanel = 0
# get away <div class="feEditAdvanced-firstWrapper" ...> if your logged into the backend
styles.content.get.stdWrap >
# Use custom template for List.html of EXT:fluid_styled_content
lib.contentElement.templateRootPaths.5 = EXT:news/Resources/Private/Examples/Rss/fluid_styled_content/Templates
pageNewsRSS = PAGE
pageNewsRSS.typeNum = {$plugin.tx_news.rss.channel.typeNum}
pageNewsRSS.10 < styles.content.get
pageNewsRSS.10.select.where = colPos=0 AND list_type = "news_pi1"
pageNewsRSS.10.select {
orderBy = sorting ASC
max = 1
}
config {
# deactivate Standard-Header
disableAllHeaderCode = 1
# no xhtml tags
xhtml_cleaning = none
admPanel = 0
# define charset
metaCharset = utf-8
# you need an english locale to get correct rfc values for <lastBuildDate>, ...
locale_all = en_EN
# CMS 8 (adjust if using ATOM)
additionalHeaders.10.header = Content-Type:application/xml;charset=utf-8
disablePrefixComment = 1
baseURL = {$plugin.tx_news.rss.channel.link}
absRefPrefix = {$plugin.tx_news.rss.channel.link}
linkVars >
}
# set the format
plugin.tx_news.settings.format = xml
[global]
**Some explanations**
The page object pageNewsRSS will render only those content elements which are in colPos 0 and are a news plugin. Therefore all other content elements won't be rendered in the RSS feed.
Misc
^^^^
RSS feed configuration
""""""""""""""""""""""
Don't forget to configure the RSS feed properly as the sample template won't fulfill your needs completely. Please look up the constants and change the mentioned settings.
.. code-block:: typoscript
plugin.tx_news.rss.channel {
title = Dummy Title
description =
link = http://example.com
language = en-gb
copyright = TYPO3 News
category =
generator = TYPO3 EXT:news
}
Add a link to the RSS feed in the list view
"""""""""""""""""""""""""""""""""""""""""""
To be able to render a link in the header section of the normal page which points to the RSS feed you can use something like this in your List.html Fluid template.
.. code-block:: html
<n:headerData>
<link rel="alternate" type="application/rss+xml" title="RSS 2.0" href="{f:uri.page(pageType: settings.list.rss.channel.typeNum)}" />
</n:headerData>
Troubleshooting
^^^^^^^^^^^^^^^
Entity 'nbsp' not defined
"""""""""""""""""""""""""
If you are getting this error, the easiest thing is to replace the character by using TypoScript:
.. code-block:: typoscript
pageNewsRSS.10.stdWrap.replacement {
10 {
search = &nbsp;
replace = &#160;
}
}

View File

@@ -0,0 +1,274 @@
.. include:: /Includes.rst.txt
.. _seo:
===
SEO
===
This chapters covers all configurations which are relevant for search engine optimization
regarding the news extension.
.. note::
All settings described require TYPO3 9 and the the system extension "seo" installed.
.. only:: html
.. contents::
:local:
:depth: 2
Page title for single news
--------------------------
EXT:news implements a custom *pageTitleProvider* `\GeorgRinger\News\Seo\NewsTitleProvider` which is called through the controller.
It can be configured using TypoScript:
.. code-block:: typoscript
plugin.tx_news.settings.detail {
pageTitle = 1
pageTitle {
# Register alternative provider
provider = GeorgRinger\News\Seo\NewsTitleProvider
# Comma separated list of properties which should be checked, 1st value is used
properties = teaser,title
}
}
It is also possible to set the page title through the template by using:
.. code-block:: html
<n:titleTag>
<f:format.htmlentitiesDecode>{newsItem.title}</f:format.htmlentitiesDecode>
</n:titleTag>
Please disable the usage of the page title provider by using
.. code-block:: typoscript
plugin.tx_news.settings.detail.pageTitle = 0
XML Sitemap
-----------
The sitemap includes links to all news records. This makes it easier for search engines to find all news records and to index those.
Depending on your requirements you can either use the simple sitemap provider from the Core or a custom one shipped with EXT:news.
Basic sitemap
~~~~~~~~~~~~~
The Core ships a basic sitemap configuration which can also be used for news records:
.. code-block:: typoscript
plugin.tx_seo.config {
xmlSitemap {
sitemaps {
news {
provider = TYPO3\CMS\Seo\XmlSitemap\RecordsXmlSitemapDataProvider
config {
table = tx_news_domain_model_news
additionalWhere =
sortField = sorting
lastModifiedField = tstamp
changeFreqField = sitemap_changefreq
priorityField = sitemap_priority
pid = 26
recursive = 2
url {
pageId = 25
fieldToParameterMap {
uid = tx_news_pi1[news]
}
additionalGetParameters {
tx_news_pi1.controller = News
tx_news_pi1.action = detail
}
}
}
}
}
}
}
Extended sitemap
~~~~~~~~~~~~~~~~
The :php:`GeorgRinger\News\Seo\NewsXmlSitemapDataProvider` provides the same feature set as
:php:`RecordsXmlSitemapDataProvider` but with some additional ones on top:
- If you are using the feature to define the detail page through the field
:guilabel:`Single-view page for news from this category` of a :sql:`sys_category` you need to use a custom provider.
- If you are need urls containing day, month or year information
- Setting :typoscript:`excludedTypes` to exclude certain news types from the sitemap
- Setting :typoscript:`googleNews` to load the news differently as required for Google News (newest news first and limit to last two days)
To enable the category detail page handling, checkout the setting :typoscript:`useCategorySinglePid = 1` in the following full example:
.. code-block:: typoscript
plugin.tx_seo {
config {
xmlSitemap {
sitemaps {
news {
provider = GeorgRinger\News\Seo\NewsXmlSitemapDataProvider
config {
excludedTypes = 1,2
additionalWhere =
## enable these two lines to generate a Google News sitemap
# template = EXT:news/Resources/Private/Templates/News/GoogleNews.xml
# googleNews = 1
sortField = datetime
lastModifiedField = tstamp
pid = 84
recursive = 2
url {
pageId = 116
useCategorySinglePid = 1
hrDate = 0
hrDate {
day = j
month = n
year = Y
}
fieldToParameterMap {
uid = tx_news_pi1[news]
}
additionalGetParameters {
tx_news_pi1.controller = News
tx_news_pi1.action = detail
}
}
}
}
}
}
}
}
Multiple Sitemaps
~~~~~~~~~~~~~~~~~
With TYPO3 10 it is possible to define multiple sitemaps. This can be used to define a normal sitemap and one for google news. This example adds another sitemap for the google news and defines a new type.
.. code-block:: typoscript
plugin.tx_seo {
config {
xmlSitemap {
sitemaps {
news {
provider = GeorgRinger\News\Seo\NewsXmlSitemapDataProvider
config {
# ...
}
}
}
googleNewsSitemap {
sitemaps {
news < plugin.tx_seo.config.xmlSitemap.sitemaps.news
news {
config {
template = EXT:news/Resources/Private/Templates/News/GoogleNews.xml
googleNews = 1
}
}
}
}
}
}
seo_sitemap_news < seo_sitemap
seo_sitemap_news {
typeNum = 1533906436
10.sitemapType = googleNewsSitemap
}
This sitemap can be added in the site config so it has a nice url:
.. code-block:: yaml
:linenos:
routeEnhancers:
PageTypeSuffix:
map:
news_sitemap.xml: 1533906436
.. _seo_language_menus:
Language menu on news detail pages
----------------------------------
If a language menu is rendered on a detail page and the languages are configured to use a strict mode, the following snippet helps you to setup a proper menu.
If no translation exists, the property `available` is set to `false` - just as if the current page is not translated.
.. code-block:: typoscript
10 = TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor
10 {
as = languageMenu
addQueryString = 1
}
11 = GeorgRinger\News\DataProcessing\DisableLanguageMenuProcessor
# comma separated list of language menu names
11.menus = languageMenu
See also chapter :ref:`LanguageMenuProcessor <dataProcessing_LanguageMenuProcessor>`.
Hreflang on news detail pages
-----------------------------
If using languages with the language mode `strict`, the hreflang tag must only be generated if the according news record is translated as well!
.. note::
This feature is only supported by TYPO3 10 and up, described
in :ref:`TYPO3 Explained, ModifyHrefLangTagsEvent<t3coreapi:ModifyHrefLangTagsEvent>`.
EXT:news reduces the rendered hreflang attributes by using this event and checking the availability of the records.
Check availability in Fluid templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If you are building a language menu and want to check if the news record is available, you can use the ViewHelper
:html:`<n:check.pageAvailableInLanguage language="{languageId}">`. A full example can look like this:
.. code-block:: html
<ul>
<f:for each="{LanguageMenu}" as="item">
<f:if condition="{item.available}">
<n:check.pageAvailableInLanguage language="{item.languageId}">
<li class="language-switch {f:if(condition:item.active, then:'active')}">
<a href="{item.link}">{item.navigationTitle}</a>
</li>
</n:check.pageAvailableInLanguage>
</f:if>
</f:for>
</ul>
Robots: allow indexing of news records, but set 'noindex' to the detail page
----------------------------------------------------------------------------
By default, the detail page will be listed in the SEO sitemap.
But in most cases, you don't want the page itself to be indexed by search engines (means: without a news record to be shown by the plugin).
If you just disable *Index this page* (`no_index`) in the page properties, the robots meta tag with *noindex* value will also be applied to the news records.
Solution: You can use the following TypoScript condition to allow search engines to index the page again, if a news record is rendered:
.. code-block:: typoscript
[traverse(request.getQueryParams(), 'tx_news_pi1/news') > 0]
page.meta.robots = index,follow
page.meta.robots.replace = 1
[global]
An important part is the `replace` option. The MetaTag API of TYPO3 will then replace tags which were set before.

View File

@@ -0,0 +1,64 @@
.. include:: /Includes.rst.txt
.. _general_tsconfig_examples:
======================
TSconfig code snippets
======================
Page TSconfig from can be used to influence display and behaviour of fields and
forms in the backend. The following examples are for your convenience only, they
are possible with any record type in TYPO3. Read more about what you can do with
page TSconfig in the :doc:`TSconfig Reference <t3tsconfig:Index>`.
You want to add your example here? Hit the "Edit on Github" button in the top
right and make a pull request on Github.
Setting default values
======================
It is possible to set default values for each field in the backend:
.. code-block:: typoscript
TCAdefaults.tx_news_domain_model_news {
author = Jon Doe
notes = Someone forgot to change the notes....
}
Categories
==========
Set a default category
----------------------
Setting default values also works for categories:
.. code-block:: typoscript
TCAdefaults.tx_news_domain_model_news {
categories = 9
}
Limit categories to just one or several roots
---------------------------------------------
In many installations categories are used for multiple purposes. If you want
to use certain category trees only in certain page trees or only for your news
records, you can set the following
.. versionadded:: TYPO3 11.4
:typoscript:`treeConfig.startingPoints` was added with TYPO3 11.4
.. code-block:: typoscript
TCEFORM.tx_news_domain_model_news.categories.config.treeConfig.startingPoints = 8,42
.. deprecated:: TYPO3 11.4
Before TYPO3 11.4 it was only possible to set one value as category root:
.. code-block:: typoscript
TCEFORM.tx_news_domain_model_news.categories.config.treeConfig.rootUid = 42
See also :ref:`TSconfig Reference, treeConfig <t3tsconfig:pageTsConfigTceFormConfigTreeConfig>`.

View File

@@ -0,0 +1,75 @@
.. include:: /Includes.rst.txt
.. _addCustomType:
=================
Custom news types
=================
Out of the box news comes with three types built in:
- "News": Default news record
- "Internal Page": The news record is linked to a regular page.
- "External Page": The news record is linked to an external URL.
To add your custom type, you have to follow the steps below.
.. note::
In this example the new type will be called 'myCustomNewsType' and is configured to only show the fields 'title' and 'bodytext'.
1) Class Mapping
----------------
Create a file `Configuration/Extbase/Persistence/Classes.php`
.. code-block:: php
<?php
return [
\GeorgRinger\News\Domain\Model\News::class => [
'subclasses' => [
3 => \Vendor\ExtName\Domain\Model\MyCustomNewsType::class,
]
],
\Vendor\ExtName\Domain\Model\MyCustomNewsType::class => [
'tableName' => 'tx_news_domain_model_news',
'recordType' => 3,
]
];
2) TCA
------
In this example, the new type is configured to show the fields `bodytext` and `title`.
Therefore, create the file `Configuration/TCA/Overrides/tx_news_domain_model_news.php`.
.. code-block:: php
<?php
if (!defined('TYPO3_MODE')) {
die ('Access denied.');
}
$GLOBALS['TCA']['tx_news_domain_model_news']['columns']['type']['config']['items']['3'] =
['myCustomNewsType', 3] ;
$GLOBALS['TCA']['tx_news_domain_model_news']['types']['3'] = [
'showitem' => 'title, bodytext'
];
3) Custom class
---------------
.. code-block:: php
<?php
namespace Vendor\ExtName\Domain\Model;
class MyCustomNewsType extends \GeorgRinger\News\Domain\Model\News {
}
.. hint:: This is a very basic example.
It would also be possible to use your custom news type to show custom fields.
How to add custom fields to news is documented :ref:`here <proxyClassGenerator>`.

View File

@@ -0,0 +1,38 @@
.. include:: /Includes.rst.txt
.. _dataProcessing_AddNewsToMenuProcessor:
======================
AddNewsToMenuProcessor
======================
.. versionadded:: 7.2.0
With version 7.2 a new data processor, :php:`AddNewsToMenuProcessor` has
been added which is useful for detail pages to add the news record as
fake menu entry.
This data processor can be used to add the currently displayed news record
to a pages breadcrumb.
Usage
=====
.. code-block:: typoscript
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
as = breadcrumbMenu
special = rootline
# [...] further configuration
}
20 = GeorgRinger\News\DataProcessing\AddNewsToMenuProcessor
20.menus = breadcrumbMenu,specialMenu
The property :typoscript:`menus` is a comma-separated list of
:php:`MenuProcessors` that shall have the currently displayed news record
attached as fake menu entry.
Examples
========
See :ref:`Tutorial: Breadcrumb based on data processing and Fluid <breadcrumbFluid>`.

View File

@@ -0,0 +1,15 @@
.. include:: /Includes.rst.txt
.. _dataProcessing:
===============
Data processing
===============
The extension news currently contains the following data processors:
.. toctree::
:titlesonly:
AddNewsToMenuProcessor
LanguageMenuProcessor

View File

@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _dataProcessing_LanguageMenuProcessor:
=====================
LanguageMenuProcessor
=====================
.. versionadded:: 8.5.0
With version 8.5 a new data processor, :php:`LanguageMenuProcessor` has
been added.
This data processor renders a correct language menu on detail pages, which
respects if a news record is translated or not.
Usage
=====
.. code-block:: typoscript
10 = TYPO3\CMS\Frontend\DataProcessing\LanguageMenuProcessor
10 {
as = languageMenu
addQueryString = 1
}
11 = GeorgRinger\News\DataProcessing\DisableLanguageMenuProcessor
11.menus = languageMenu
The property :typoscript:`menus` is a comma-separated list of
:php:`MenuProcessors`.
If a language menu is rendered on a detail page and the
languages are configured to use a strict mode this data processor can be used:
If no translation exists, the property `available` in the
:php:`LanguageMenuProcessor` is set to `false` - just as if the current page
is not translated.
Examples
========
See :ref:`SEO: Language menu on news detail pages <seo_language_menus>`.

View File

@@ -0,0 +1,144 @@
.. include:: /Includes.rst.txt
.. _demands:
=======
Demands
=======
A demand is a configuration object used by the repository to decide which
news records should be fetched.
The default demand class implementation for the frontend output of news
is :php:`GeorgRinger\News\Domain\Model\Dto\NewsDemand`. It has a couple of
useful properties that can be used to filter news records, for example
:php:`$categories`, :php:`$searchFields`, :php:`$author` and many more.
There is also the property :php:`$customSettings` an array of custom settings
by extensions. You should use your extension name as key in this array.
Demand objects can be changed in a couple of ways, see below:
URL Parameter
=============
The URL parameter :code:`overwriteDemand` can be used to override properties
of the demand.
You can set this parameter in a Fluid link (see
:ref:`Set overwriteDemand in Frontend <overwriteDemand-in-frontend>`) or via
TypoScript in a typolink (See
:ref:`TypoScript reference: typolink <t3tsref:typolink>`).
It would even be possible to configure a :ref:`LinkHandler <linkhandler>`
for this parameter.
.. important::
The checkbox :guilabel:`Disable override demand` in the list plugin
(Tab Additional) must **not** be set to allow overriding the properties.
Additionally the TypoScript setting
:ref:`settings.disableOverrideDemand <tsDisableOverrideDemand>` must be set to
:code:`0`.
Via TypoScript
==============
TypoScript can be used to define a class containing a
:ref:`custom implementation <demand_custom>`
of the demand object. This can be achieved by the TypoScript setting
:ref:`settings.demandClass <tsDemandClass>`.
Custom controllers
==================
The demand object can be used in a custom controller used in an extension
extending EXT:news. Read more about using a demand object in a custom
controller:
:ref:`Extension based on EXT:news: FilterController.php <extension_custom_controller>`.
Hooks
=====
Several hooks can be used to influence the demand object and its usage.
Hook findDemanded
-----------------
The hook :code:`findDemanded` is very
powerful. It allows to modify the query used to fetch the news records depending
on values set in the demand object. You can find an example of how to use it in
the chapter :ref:`Hooks: Example findDemanded <hooks_example_findDemanded>`.
Hook createDemandObjectFromSettings
-----------------------------------
The hook :code:`createDemandObjectFromSettings`
(:php:`$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Controller/NewsController.php']['createDemandObjectFromSettings']`)
can be used to influence the settings of the demand object as it is used in
most standard actions in the :php:`NewsController`, such as the
:php:`listAction()`, :php:`selectedListAction()` and :php:`detailAction()`.
This hook can be used to insert settings from custom TypoScript or custom
FlexForm configuration into the demand object. (See also
:ref:`Extend FlexForms <extendFlexforms>`)
Events
======
Multiple events can change or use demand objects. For example the events of
the main actions in the :php:`NewsController`, for example
:php:`NewsListActionEvent` and :php:`NewsDetailActionEvent`. For more
information refer to the chapter :ref:`Events <events>`.
.. _demand_custom:
Custom demand class
===================
All custom frontend news demand classes must extend
:php:`GeorgRinger\News\Domain\Model\Dto\NewsDemand`. The demand object is
a simple configuration object. It should contain no business logic. For each
property there must be a setter and a getter.
Example:
.. code-block:: php
<?php
namespace Vendor\MyNews\Domain\Model\Dto;
use \GeorgRinger\News\Domain\Model\Dto\NewsDemand;
class MyNewsDemand extends NewsDemand {
/**
* @var string
*/
protected $myCustomField = '';
/**
* Set myCustomField
*
* @param string $myCustomField
* @return NewsDemand
*/
public function setMyCustomField(string $myCustomField): NewsDemand
{
$this->myCustomField = $myCustomField;
return $this;
}
/**
* Get myCustomField
*
* @return string
*/
public function getMyCustomField(): string
{
return $this->myCustomField;
}
}

View File

@@ -0,0 +1,70 @@
.. include:: /Includes.rst.txt
.. _eventsTutorial:
======
Events
======
Several events can be used to modify the behaviour of EXT:news.
.. only:: html
.. contents::
:local:
:depth: 1
Connect to Event
----------------
To connect to an event, you need to register an event listener in your custom
extension. All what it needs is an entry in your
:file:`Configuration\Services.yaml` file:
.. code-block:: yaml
services:
Vendor\Extension\EventListener\YourListener:
tags:
- name: event.listener
identifier: 'your-self-choosen-identifier'
method: 'methodToConnectToEvent'
event: GeorgRinger\News\Event\NewsListActionEvent
Write your EventListener
------------------------
An example event listener can look like this:
.. code-block:: php
<?php
declare(strict_types=1);
namespace Vendor\Extension\EventListener;
use GeorgRinger\News\Event\NewsListActionEvent;
/**
* Use NewsListActionEvent from ext:news
*/
class YourListener
{
/**
* Do what you want...
*/
public function methodToConnectToEvent(NewsListActionEvent $event): void
{
$values = $event->getAssignedValues();
// Do some stuff
$event->setAssignedValues($values);
}
}
Available events
----------------
Check out the :ref:`Events reference <referenceEvents>`.

View File

@@ -0,0 +1,134 @@
.. include:: /Includes.rst.txt
.. _extendFlexforms:
================
Extend FlexForms
================
Following fields of the plugin configuration can be extended without
overriding the complete FlexForm configuration.
.. only:: html
.. contents::
:local:
:depth: 1
Selectbox "Sort by"
^^^^^^^^^^^^^^^^^^^
The sorting can be extended by adding the value to
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['orderByNews']
Default values are: tstamp,datetime,crdate,title
Additional Actions
^^^^^^^^^^^^^^^^^^
If you need an additional action to select, you can extend it by using:
.. code-block:: php
// Add an additional action: Key is "Controller->action", value is label
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['switchableControllerActions']['newItems']['News->byFobar'] = 'A fobar action';
Remove fields in additional actions
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you define an additional action, you won't need all available fields which are available inside the FlexForms. If you want to hide some fields,
take a look at the hook inside the class Hooks/BackendUtility.php:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Hooks/BackendUtility.php']['updateFlexforms']
Additional Template Selector
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you need a kind of template selector inside a plugin, you can add
your own selections by adding those to
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['templateLayouts']['myext'] = array('My Title', 'my value');
You can then access the variable in your template with
:code:`{settings.templateLayout}` and use it for a condition or whatever.
Extend FlexForms with custom fields
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you need additional fields in the FlexForm configuration, this can be done by using a hook in the Core.
**Register the hook**
Add this to the ``ext_localconf.php`` of your extension:
.. code-block:: php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][\TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools::class]['flexParsing'][]
= \Vendor\ExtKey\Hooks\FlexFormHook::class;
**Add the hook**
Create the class ``FlexFormHook`` in your extension in ``Classes/Hooks/FlexFormHook.php`` and add the path to an additional
FlexForm file.
.. code-block:: php
<?php
namespace Vendor\ExtKey\Hooks;
use TYPO3\CMS\Core\Core\Environment;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class FlexFormHook
{
/**
* @param array $dataStructure
* @param array $identifier
* @return array
*/
public function parseDataStructureByIdentifierPostProcess(array $dataStructure, array $identifier): array
{
if ($identifier['type'] === 'tca' && $identifier['tableName'] === 'tt_content' && $identifier['dataStructureKey'] === 'news_pi1,list') {
$file = Environment::getPublicPath() . '/typo3conf/ext/extKey/Configuration/Example.xml';
$content = file_get_contents($file);
if ($content) {
$dataStructure['sheets']['extraEntry'] = GeneralUtility::xml2array($content);
}
}
return $dataStructure;
}
}
**Create the FlexForm file**
Create the FlexForm file you just referenced in the hook. This can look like that.
.. code-block:: html
<extra>
<ROOT>
<TCEforms>
<sheetTitle>Fo</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<settings.postsPerPage>
<TCEforms>
<label>Max. number of posts to display per page</label>
<config>
<type>input</type>
<size>2</size>
<eval>int</eval>
<default>3</default>
</config>
</TCEforms>
</settings.postsPerPage>
</el>
</ROOT>
</extra>

View File

@@ -0,0 +1,312 @@
.. include:: /Includes.rst.txt
.. _ext-based-on-news:
Extensions based on EXT:news
============================
If you are using news records but need custom configuration and custom settings, you should think of creating a separate extension. This is really simple, just take a look at the following example.
.. only:: html
.. contents::
:local:
:depth: 1
Setup of the extension
----------------------
As a demonstration, a new extension with the extension key ``news_filter`` will be created. The following files and its content is required.
ext_emconf.php
^^^^^^^^^^^^^^
This file containts the basic information about its extension like name, version, author...
.. code-block:: php
<?php
$EM_CONF[$_EXTKEY] = [
'title' => 'News Filter',
'description' => 'News filtering',
'category' => 'fe',
'author' => 'John Doe',
'author_email' => 'john@doe.net',
'shy' => '',
'dependencies' => '',
'conflicts' => '',
'priority' => '',
'module' => '',
'state' => 'stable',
'internal' => '',
'uploadfolder' => 0,
'modify_tables' => '',
'clearCacheOnLoad' => 1,
'lockType' => '',
'author_company' => '',
'version' => '1.0.0',
'constraints' => [
'depends' => [
'typo3' => '7.6.0-8.9.99',
],
'conflicts' => [],
'suggests' => [],
],
'suggests' => [],
];
ext_localconf.php
^^^^^^^^^^^^^^^^^
Create a basic plugin with one action called ``list``.
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
$boot = function () {
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'GeorgRinger.news_filter',
'Filter',
[
'Filter' => 'list',
]
);
};
$boot();
unset($boot);
Configuration/TCA/Overrides/tt_content.php
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Register the plugin:
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
/***************
* Plugin
*/
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'news_filter',
'Filter',
'Some demo'
);
.. _extension_custom_controller:
Classes/Controller/FilterController.php
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Create a basic controller with the mentioned action.
.. code-block:: php
<?php
namespace GeorgRinger\NewsFilter\Controller;
use GeorgRinger\News\Domain\Model\Dto\NewsDemand;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
class FilterController extends ActionController
{
public function listAction()
{
$demand = $this->createDemandObject();
$this->view->assignMultiple([
'news' => $this->newsRepository->findDemanded($demand)
]);
}
/**
* @return NewsDemand
*/
protected function createDemandObject()
{
$demand = $this->objectManager->get(NewsDemand::class);
$demand->setLimit(10);
return $demand;
}
/**
* @var \GeorgRinger\News\Domain\Repository\NewsRepository
* @inject
*/
protected $newsRepository;
}
Resources/Private/Templates/Filter/List.html
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Create the template:
.. code-block:: html
<f:if condition="{news}">
<f:then>
<div class="row">
<f:for each="{news}" as="newsItem">
<div class="col-md-3">
<h5>{newsItem.title}</h5>
</div>
</f:for>
</div>
</f:then>
<f:else>
<div class="alert alert-danger">No news found</div>
</f:else>
</f:if>
Setup
-----
After enabling the extension in the Extension Manager and creating a plugin "Filter" on a page, you will see up to 10 news records of your system.
.. hint::
If your installation is based on composer, you need to add the classes to the PSR-4 section.
.. code-block:: js
"autoload": {
"psr-4": {
"GeorgRinger\\NewsFilter\\": "typo3conf/ext/news_filter/Classes/"
}
}
Configuration
-------------
There are multiple ways how to configure which news records should be shown. The fastest way is to hardcode the configuration.
Hardcode it
^^^^^^^^^^^
By modifying the controller with the following code, you will change the output to show only those news records which fulfill the following requirements:
- The pid is ``123``
- The author is ``John``
- The id of the records is neither ``12`` nor ``45``.
.. code-block:: php
/**
* @return NewsDemand
*/
protected function createDemandObject()
{
$demand = $this->objectManager->get(NewsDemand::class);
$demand->setStoragePage('123');
$demand->setAuthor('John');
$demand->setHideIdList('12,45');
return $demand;
}
Use FlexForms
^^^^^^^^^^^^^
Flexforms are a powerful tool to let editors configure plugins.
Configuration/TCA/Overrides/tt_content.php
""""""""""""""""""""""""""""""""""""""""""
Exchange the existing file with the following content.
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
/***************
* Plugin
*/
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
'news_filter',
'Filter',
'Some demo'
);
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_excludelist']['newsfilter_filter'] = 'recursive,select_key,pages';
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['newsfilter_filter'] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue('newsfilter_filter',
'FILE:EXT:news_filter/Configuration/FlexForms/flexform_news_filter.xml');
Configuration/FlexForms/flexform_news_filter.xml
""""""""""""""""""""""""""""""""""""""""""""""""
The syntax of ``FlexForms`` is identical to the one of ``TCA`` with the only difference that it is written in XML instead of PHP.
.. code-block:: xml
<T3DataStructure>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_tab.settings
</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<settings.startingpoint>
<TCEforms>
<label>LLL:EXT:core/Resources/Private/Language/locallang_general.xlf:LGL.startingpoint</label>
<config>
<type>group</type>
<internal_type>db</internal_type>
<allowed>pages</allowed>
<size>3</size>
<maxitems>50</maxitems>
<minitems>0</minitems>
<wizards>
<suggest>
<type>suggest</type>
<default>
<searchWholePhrase>1</searchWholePhrase>
</default>
</suggest>
</wizards>
</config>
</TCEforms>
</settings.startingpoint>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
Important is that each element's name is prepended with ``settings.``.
.. hint::
Take a look at the FlexForms of the news extension for inspiration. You can even just copy & paste settings from there.
The file can be found at ``EXT:news/Configuration/FlexForms/flexform_news.xml``.
Classes/Controller/FilterController.php
"""""""""""""""""""""""""""""""""""""""
Adopt the controller to use the settings instead of the hardcoded ones.
.. code-block:: php
/**
* @return NewsDemand
*/
protected function createDemandObject()
{
$demand = $this->objectManager->get(NewsDemand::class);
// Because of the naming "<settings.startingpoint>", you can use $this->settings['startingpoint']
$demand->setStoragePage($this->settings['startingpoint']);
$demand->setLimit(10);
return $demand;
}

View File

@@ -0,0 +1,111 @@
.. include:: /Includes.rst.txt
.. _hooks:
=====
Hooks
=====
Several hooks can be used to modify the behaviour of EXT:news.
.. only:: html
.. contents::
:local:
:depth: 1
Hooks
-----
.. _hooks_example_findDemanded:
Domain/Repository/AbstractDemandedRepository.php findDemanded
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This hook is very powerful, as it allows to modify the query used to fetch the news records.
Example
"""""""
This examples modifies the query and adds a constraint that only news records are shown which contain the word *yeah*.
First, register your implementation in the file ``ext_localconf.php``:
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Domain/Repository/AbstractDemandedRepository.php']['findDemanded'][$_EXTKEY]
= 'YourVendor\\Extkey\\Hooks\\Repository->modify';
Now create the file ``Classes/Hooks/Repository.php``:
.. code-block:: php
<?php
namespace YourVendor\Extkey\Hooks;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use \GeorgRinger\News\Domain\Repository\NewsRepository;
class Repository {
public function modify(array $params, NewsRepository $newsRepository) {
$this->updateConstraints($params['demand'], $params['respectEnableFields'], $params['query'], $params['constraints']);
}
/**
* @param \GeorgRinger\News\Domain\Model\Dto\NewsDemand $demand
* @param bool $respectEnableFields
* @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
* @param array $constraints
*/
protected function updateConstraints($demand, $respectEnableFields, \TYPO3\CMS\Extbase\Persistence\QueryInterface $query, array &$constraints) {
$subject = 'yeah';
$constraints[] = $query->like('title', '%' . $subject . '%');
}
}
.. hint:: Please change the vendor and extension key to your real life code.
Controller/NewsController overrideSettings
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Use this hook to change the final settings which are for building queries, for the template, ...
Example
"""""""
This examples modifies the settings by changing the category selection.
First, register your implementation in the file ``ext_localconf.php``:
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['Controller/NewsController.php']['overrideSettings'][$_EXTKEY]
= 'YourVendor\\Extkey\\Hooks\\NewsControllerSettings->modify';
Now create the file ``Classes/Hooks/NewsControllerSettings.php``:
.. code-block:: php
<?php
namespace YourVendor\Extkey\Hooks;
class NewsControllerSettings {
public function modify(array $params) {
$settings = $params['originalSettings'];
$settings['categories'] = '2,3';
return $settings;
}
}
.. hint:: Please change the vendor and extension key to your real life code.

View File

@@ -0,0 +1,121 @@
.. include:: /Includes.rst.txt
.. _tutorialExtendNews:
===========
Extend News
===========
.. container:: row m-0 p-0
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Custom extension <ext-based-on-news>`
.. container:: card-body
All changes listed on this page should be done in a custom
extension that extends EXT:news. Learn how to set it up.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Extend FlexForms <extendFlexforms>`
.. container:: card-body
Influence the fields available in the plugins backend FlexForm.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Events <eventsTutorial>`
.. container:: card-body
Extend the code of EXT:news by using PSR-14 Events.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Hooks <hooks>`
.. container:: card-body
If there is no PSR-14 Event, try using a hook instead.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Demands <demands>`
.. container:: card-body
Learn how to filter and sort the displayed news using demands.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Data processing <dataProcessing>`
.. container:: card-body
Display news in menus using data processing
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Add custom fields <proxyClassGenerator>`
.. container:: card-body
Learn how to add custom fields to news records and extend the
:php:`News` model using the ProxyClassGenerator
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Custom news types <addCustomType>`
.. container:: card-body
Add additional custom news types
.. toctree::
:maxdepth: 5
:titlesonly:
:hidden:
ExtensionBasedOnNews/Index
ExtendFlexforms/Index
Events/Index
Hooks/Index
Demands/Index
DataProcessing/Index
ProxyClassGenerator/Index
AddCustomType/Index

View File

@@ -0,0 +1,182 @@
.. include:: /Includes.rst.txt
.. _proxyClassGenerator:
=================
Add custom fields
=================
Follow this chapter to learn how to add new fields or actions.
It is important to know how this concept is implemented. If a class should be extended, EXT:news will generate
a new file containing the original class of the extension itself and all other classes which should extended it.
Take a look at the following 2 working examples:
- Add relation to a FE user: https://github.com/cyberhouse/t3ext-newsauthor
- Add an image gallery to a news record: https://github.com/cyberhouse/t3ext-news_gallery
.. attention:: This generator works only with the news version 3.2.0 or higher.
.. warning:: The drawbacks are easy to identify:
- Don't use any use statements as those are currently ignored!
- It is not possible to override an actual method or property!
The files are saved by using the Caching Framework in the directory :file:`typo3temp/Cache/Code/news`.
.. only:: html
.. contents::
:local:
:depth: 1
1) Add a new field in the backend
---------------------------------
To add new fields, use either the extension `extension_builder <http://typo3.org/extensions/repository/view/extension_builder>`__ or create the extension from scratch.
The extension key used in this examples is :code:`eventnews`.
Create the fields
^^^^^^^^^^^^^^^^^
3 files are basically all what you need:
ext_emconf.php
""""""""""""""
The file :file:`ext_emconf.php` holds all basic information about the extension like the title, description and version number.
.. code-block:: php
<?php
$EM_CONF[$_EXTKEY] = array(
'title' => 'news events',
'description' => 'Events for news',
'category' => 'plugin',
'author' => 'Georg Ringer',
'author_email' => '',
'state' => 'alpha',
'uploadfolder' => FALSE,
'createDirs' => '',
'clearCacheOnLoad' => TRUE,
'version' => '1.0.0',
'constraints' => array(
'depends' => array(
'typo3' => '7.6.13-8.7.99',
'news' => '6.2.0-6.9.99',
),
'conflicts' => array(),
'suggests' => array(),
),
);
SQL definition
""""""""""""""
Create the file :file:`ext_tables.sql` in the root of the extension directory with the following content:
.. code-block:: sql
# Table structure for table 'tx_news_domain_model_news '
#
CREATE TABLE tx_news_domain_model_news (
location_simple varchar(255) DEFAULT '' NOT NULL
);
TCA definition
""""""""""""""
The TCA defines which tables and fields are available in the backend and how those are rendered (e.g. as input field, textarea, select field, ...).
In this example, the table :sql:`tx_news_domain_model_news` will be extended by a simple input field.
Therefore, create the file :file:`Configuration/TCA/Overrides/tx_news_domain_model_news.php`.
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
$fields = array(
'location_simple' => array(
'exclude' => 1,
'label' => 'My location',
'config' => array(
'type' => 'input',
'size' => 15
),
)
);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns('tx_news_domain_model_news', $fields);
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes('tx_news_domain_model_news', 'location_simple');
Install the extension
^^^^^^^^^^^^^^^^^^^^^
Now you should be able to install the extension and if you open a news record, you should see the new field in the last tab.
.. TODO: what if something wrong
2) Register the class
---------------------
Until now, EXT:news won't use the new field because it doesn't know about it. To change that, you need to register your new model.
Registration
^^^^^^^^^^^^
Create the file :file:`ext_localconf.php` in the root of the extension:
.. code-block:: php
<?php
defined('TYPO3_MODE') or die();
$GLOBALS['TYPO3_CONF_VARS']['EXT']['news']['classes']['Domain/Model/News']['eventnews'] = 'eventnews';
:php:`Domain/Model/News` is the namespace to the class which should be extended and :code:`eventnews` is the extension key.
Custom class
^^^^^^^^^^^^
As the class :php:`Domain/Model/News` should be extended, create a file at the same path in the own extension which is
:file:`typo3conf/ext/eventnews/Classes/Domain/Model/News.php`:
.. code-block:: php
<?php
namespace GeorgRinger\Eventnews\Domain\Model;
/**
* News
*/
class News extends \GeorgRinger\News\Domain\Model\News {
/**
* @var string
*/
protected $locationSimple;
/**
* @return string
*/
public function getLocationSimple() {
return $this->locationSimple;
}
/**
* @param string $locationSimple
*/
public function setLocationSimple($locationSimple) {
$this->locationSimple = $locationSimple;
}
}
.. hint::
If you are using the extension :file:`extension_builder`, this class might have been created for you already.
Clear system cache
^^^^^^^^^^^^^^^^^^
Now it is time to clear the :guilabel:`system cache`, either via the dropdown in the backend or in the module :guilabel:`Admin Tools`.

View File

@@ -0,0 +1,27 @@
.. include:: /Includes.rst.txt
.. _tutorialsExternal:
==================
External tutorials
==================
There are already some additional 3rd party tutorials about the extension "news".
Video tutorials by jweiland
^^^^^^^^^^^^^^^^^^^^^^^^^^^
5 german video tutorials by Jochen Weiland which can be found at http://jweiland.net/typo3-hosting/service/video-anleitungen/typo3-extensions/news.html.
- Installation & Configuration: http://vimeo.com/63231058
- Create an article: http://vimeo.com/63231385
- Output in frontend: http://vimeo.com/63231754
- News archive: http://vimeo.com/63232250
- Multilanguage: http://vimeo.com/63232527
Add links to your own tutorials
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you have written an own tutorial or found one which is worth to be mentioned,
please open an issue in the bugtracker.

View File

@@ -0,0 +1,69 @@
.. include:: /Includes.rst.txt
.. _tutorials:
=========
Tutorials
=========
.. container:: row m-0 p-0
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Best practice <tutorialsBestPractice>`
.. container:: card-body
Assorted small tutorials of how to achieve goals around EXT:news.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Templates <templatingExamples>`
.. container:: card-body
Tutorials with examples on how to use customized Fluid templates.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Extend News <tutorialExtendNews>`
.. container:: card-body
In-depth tutorials for developers, who want to extend EXT:news
with their own custom extensions.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`External tutorials <tutorialsExternal>`
.. container:: card-body
A list of recommended external tutorials, some of them in German.
.. toctree::
:maxdepth: 5
:titlesonly:
:hidden:
BestPractice/Index
ExtendNews/Index
Templates/Index
ExternalTutorials

View File

@@ -0,0 +1,50 @@
.. include:: /Includes.rst.txt
.. _templatesGroupNews:
==================
Group news records
==================
.. tip::
This is a feature delivered by Fluid, so you can use it also in other extensions and projects.
The following example will group all given news records by the property "firstCategory".
.. code-block:: html
<f:if condition="{news}">
<f:then>
<div style="border:1px solid red">
<f:groupedFor each="{news}" as="groupedNews" groupBy="firstCategory" groupKey="cat">
<div style="border:1px solid blue;padding:10px;margin:10px;">
<h1>{cat.title}</h1>
<f:for each="{groupedNews}" as="newsItem">
<div style="border:1px solid pink;padding:5px;margin:5px;">
{newsItem.title}
</div>
</f:for>
</div>
</f:groupedFor>
</div>
</f:then>
<f:else>
<div class="no-news-found">
<f:translate key="list_nonewsfound"/>
</div>
</f:else>
</f:if>
Keep an eye on performance!
===========================
To be able to group the records, Fluid will load every record itself and
groups those afterwards.
If you plan to group many records just for getting something like a count,
maybe it is better to fire the query directly and don't use Fluid for that.
However if the result is on a cacheable page, the issue is only relevant on the
first hit.

View File

@@ -0,0 +1,135 @@
.. include:: /Includes.rst.txt
.. _templatingExamples:
=========
Templates
=========
.. container:: row m-0 p-0
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Getting started <templatingStart>`
.. container:: card-body
on using Fluid templates with EXT:news
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Bootstrap Templates <templatesBootstrap>`
.. container:: card-body
Include the templates for Twitter Bootstrap version 3 or 5 provided
by this extension.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Assorted snippets <templatesSnippets>`
.. container:: card-body
Helpful Fluid Snippets that you can use in your own news templates.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`ViewHelpers <viewHelpersTutorial>`
.. container:: card-body
A quick tutorial on how to use ViewHelpers in Fluid
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Template Selector <tutorialExtendNews>`
.. container:: card-body
Use this technique to provide different templates for the list view
and enable your editors to chose between them in the plugin settings.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Render content elements<renderContentElements>`
.. container:: card-body
Influence how content elements used within news records should be
rendered.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Group news records <templatesGroupNews>`
.. container:: card-body
Group news by a certain property in the output.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`Group news records <templatesMultipleCats>`
.. container:: card-body
Filter news by multiple categories.
.. container:: col-12 col-md-6 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header h3
.. rubric:: :ref:`overwriteDemand <templatesMultipleCats>`
.. container:: card-body
Set overwriteDemand in links.
.. toctree::
:maxdepth: 5
:titlesonly:
:hidden:
Start/Index
TwitterBootstrap/Index
Snippets/Index
ViewHelpers/Index
TemplateSelector/Index
RenderContentElements/Index
GroupNewsRecords/Index
MultiCategorySelection/Index
OverwriteDemandInFrontend/Index

View File

@@ -0,0 +1,68 @@
.. include:: /Includes.rst.txt
.. _templatesMultipleCats:
==================================
Filter news by multiple categories
==================================
The default category template `Category/List` allows only filtering by a single category. If you need to filter by multiple categories, you can use such template:
.. code-block:: html
<html xmlns:n="http://typo3.org/ns/GeorgRinger/News/ViewHelpers"
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="General" />
<!--
=====================
Templates/Category/List.html
-->
<f:section name="content">
<f:if condition="{categories}">
<f:then>
<f:render section="categoryTree" arguments="{categories:categories,overwriteDemand:overwriteDemand}" />
</f:then>
<f:else>
<f:translate key="list_nocategoriesfound" />
</f:else>
</f:if>
</f:section>
<f:section name="categoryTree">
<ul>
<f:for each="{categories}" as="category">
<li>
<n:multiCategoryLink.isCategoryActive list="{overwriteDemand.categories}" item="{category.item.uid}">
<f:then>
<f:link.page title="{category.item.title}" class="active" pageUid="{settings.listPid}"
additionalParams="{tx_news_pi1:{overwriteDemand:{categories: category.item.uid}}}">{category.item.title}
</f:link.page>
(<f:link.page title="{category.item.title}" class="active" pageUid="{settings.listPid}"
additionalParams="{n:multiCategoryLink.arguments(mode:'remove',item:category.item.uid,list:overwriteDemand.categories)}">remove
</f:link.page>)
</f:then>
<f:else>
<f:link.page title="{category.item.title}" pageUid="{settings.listPid}"
additionalParams="{tx_news_pi1:{overwriteDemand:{categories: category.item.uid}}}">{category.item.title}
</f:link.page>
(<f:link.page title="{category.item.title}" class="active" pageUid="{settings.listPid}"
additionalParams="{n:multiCategoryLink.arguments(mode:'add',item:category.item.uid,list:overwriteDemand.categories)}">add
</f:link.page>)
</f:else>
</n:multiCategoryLink.isCategoryActive>
<f:if condition="{category.children}">
<f:render section="categoryTree" arguments="{categories: category.children,overwriteDemand:overwriteDemand}" />
</f:if>
</li>
</f:for>
</ul>
</f:section>
</html>

View File

@@ -0,0 +1,26 @@
.. include:: /Includes.rst.txt
.. _overwriteDemand-in-frontend:
============================
Set overwriteDemand in links
============================
Sometimes it can be nice to define links with overwriteDemand properties in the
frontend. Use cases are:
- Change the sorting in the frontend
- Define some category filter
- ...
The following example defines the ordering
.. code-block:: html
<f:link.page additionalParams="{tx_news_pi1:{overwriteDemand:{order: 'datetime desc'}}}">
Order datetime descending
</f:link.page>
.. important::
The checkbox **Disable override demand** in the list plugin (Tab Additional)
must **not** be set to allow overriding the properties.

View File

@@ -0,0 +1,53 @@
.. include:: /Includes.rst.txt
.. _renderContentElements:
=======================
Render content elements
=======================
If news is configured to use relations to content elements, those are shown
by default in the detail view.
There are two options how to render those elements
Using TypoScript
================
This is the default way in EXT:news. A basic TypoScript configuration is used to render those. This look like this:
.. code-block:: typoscript
lib.tx_news.contentElementRendering = RECORDS
lib.tx_news.contentElementRendering {
tables = tt_content
source.current = 1
dontCheckPid = 1
}
If you need to extend this, the best way is to introduce your own TypoScript which can be saved anywhere.
This needs then to be referenced in the template.
.. code-block:: html
<f:if condition="{newsItem.contentElements}">
<f:cObject typoscriptObjectPath="lib.yourownTypoScript">{newsItem.contentElements}</f:cObject>
</f:if>
Using Fluid
===========
You can also use Fluid render the content elements. As an example:
.. code-block:: html
<f:if condition="{newsItem.contentElements}">
<f:for each="{newsItem.contentElements}" as="element">
<h3>{element.title}</h3>
<f:if condition="{element.CType} == 'text'">
{element.bodytext -> f:format.html()}
</f:if>
</f:for>
</f:if>

View File

@@ -0,0 +1,138 @@
.. include:: /Includes.rst.txt
.. _templatesSnippets:
=================
Assorted snippets
=================
This section contains snippets making EXT:news more awesome which might be useful for your projects as well.
.. only:: html
.. contents::
:local:
:depth: 1
Show FAL properties in fluid
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Every property of a file, e.g. the copyright (available via EXT:filemetadata) can be rendered in templates by using e.g. `{file.originalResource.properties.copyright}`.
A full example can look like this
.. code-block:: html
<f:for each="{newsItem.mediaNonPreviews}" as="mediaElement">
<div class="thumbnail">
<f:media file="{mediaElement}" class="img-fluid" />
<f:if condition="{mediaElement.originalResource.properties.copyright}">
<small>{mediaElement.originalResource.properties.copyright}</small>
</f:if>
</div>
</f:for>
Use `<f:debug>{mediaElement.originalResource.properties}</f:debug>` to get all available properties
Improved back links
^^^^^^^^^^^^^^^^^^^
The back link on a detail page is a fixed link to a given page. However it might be that you use multiple list views
and want to change the link depending on the given list view.
A nice solution would be to use this JavaScript jQuery snippet:
.. code-block:: javascript
if ($(".news-backlink-wrap a").length > 0) {
if(document.referrer.indexOf(window.location.hostname) != -1) {
$(".news-backlink-wrap a").attr("href","javascript:history.back();");
}
}
Creating links with Fluid
^^^^^^^^^^^^^^^^^^^^^^^^^
Besides the ViewHelper :html:`<n:link />` you can also use the ViewHelpers of Fluid itself:
.. code-block:: html
<f:link.page pageUid="13" additionalParams="{tx_news_pi1: {controller: 'News',action: 'detail', news:newsItem.uid}}">{newsItem.title}</f:link.page>
<a href="{f:uri.page(pageUid:13,additionalParams:'{tx_news_pi1:{controller:\'News\',action:\'detail\',news:newsItem.uid}}')}">{newsItem.title}</a>
Set n:link target page in Fluid
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If the detail page should not be set in the plugin or by a category, it can also be set within the template:
.. code-block:: html
<n:link
newsItem="{newsItem}"
configuration=“{parameter:settings.somePid}"
settings="{settings}" title="{newsItem.title}"><f:translate key="more-link"/></n:link>
The setting `settings.somePid` can e.g. set with `plugin.tx_news.settings.somePid=123`.
Render category rootline
^^^^^^^^^^^^^^^^^^^^^^^^
If you want to show not only the title of a single category which is related to the news item but the complete category rootline use this snippets.
.. code-block:: html
<f:if condition="{category:newsItem.firstCategory}">
<ul class="category-breadcrumb">
<f:render section="categoryBreadcrumb" arguments="{category:newsItem.firstCategory}" />
</ul>
</f:if>
and
.. code-block:: html
<f:section name="categoryBreadcrumb">
<f:if condition="{category}">
<f:if condition="{category.parentCategory}">
<f:render section="categoryBreadcrumb" arguments="{category:category.parentCategory}" />
</f:if>
<li>{category.title}</li>
</f:if>
</f:section>
Use current content element in the template
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you ever need information from the content element itself, you can use :html:`{contentObjectData.header}`.
Use current page in the template
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
If you ever need information from the current page, you can use :html:`{pageData.uid}`.
Sort tags
^^^^^^^^^
If you want to sort the tags of a news item, you can use a custom ViewHelper or :file:`EXT:vhs`:
.. code-block:: html
<ul>
<f:for each="{newsItem.tags->v:iterator.sort(order: 'ASC', sortBy: 'title')}" as="tag">
<li>{tag.title}</li>
</f:for>
</ul>
Render news items in columns
----------------------------
If you need to list news next to each other and need some additional CSS
classes, you can the following snippet.
The provided example will wrap 3 items into a div with the class "row".
.. code-block:: html
<f:for each="{news -> n:iterator.chunk(count: 3)}" as="col" iteration="cycle">
<div class="row">
<f:for each="{col}" as="newsItem">
<div class="col-md-4">
<f:render partial="List/Item" arguments="{newsItem: newsItem, settings:settings}"/>
</div>
</f:for>
</div>
</f:for>

View File

@@ -0,0 +1,269 @@
.. include:: /Includes.rst.txt
.. _templatingStart:
============================
Changing & editing templates
============================
EXT:news is using Fluid as templating engine. If you are used to Fluid
already, you might skip this section.
This documentation won't bring you all information about Fluid but only the
most important things you need for using it. You can get
more information in the TYPO3 Documentation
:ref:`TYPO3 Explained: Fluid <t3coreapi:fluid>`,
:doc:`Developing TYPO3 Extensions with Extbase and Fluid
<t3extbasebook:Index>` or many third party sites, videos and books.
.. _templatingSitepackage:
Use a site package extension
============================
It is recommended to always store overwritten templates in a custom TYPO3
extension. Usually this is done in a special extension called the
**site package**.
If you do not have a site package yet you can create one manually following
this :doc:`Official Tutorial: Site Package <t3sitepackage:Index>`.
There is also a `site package generator <https://sitepackagebuilder.com/>`__
available (Provided by Benjamin Kott).
Create a directory called
:file:`EXT:mysitepackage/Resources/Private/Extensions/News` for example and
create 3 directories therein called :file:`Templates`, :file:`Partials` and
:file:`Layouts`. In these directories you can store your version of the Fluid
templates that you need to override.
As any Extbase based extension, you can find the original templates of the
extension news in the directory :file:`EXT:news/Resources/Private/`.
If you want to change a template, copy the desired files to the
directory in your site package. If the template is in a sub folder you have to
preserve the folder structure.
For example the template:
.. code-block:: none
EXT:news/Resources/Private/Templates/News/Detail.html
would have to be copied to
.. code-block:: none
EXT:mysitepackage/Resources/Private/Extensions/News/Templates/News/Detail.html
Since your site package extends the extension news you should require news in
your :file:`composer.json`:
.. code-block:: json
:caption: :file:`EXT:mysitepackage/composer.json`
{
"require": {
"georgringer/news": "^9.0"
}
}
And / or :file:`ext_emconf.php`:
.. code-block:: php
:caption: :file:`ext_emconf.php`
$EM_CONF[$_EXTKEY] = [
// ...
'constraints' => [
'depends' => [
'news' => '9.0.0-9.99.99',
],
// ...
],
];
.. note::
It is not recommended anymore to store Fluid templates in the
:file:`fileadmin` directory.
Changing paths of the template
==============================
.. warning::
You should never edit the original templates of an extension as those changes
will vanish if you upgrade the extension.
In the most common case, where you want to override the standard news template
with your own templates you can use the TypoScript **constants** to set the
paths:
.. code-block:: typoscript
:caption: TypoScript constants
plugin.tx_news {
view {
templateRootPath = EXT:mysitepackage/Resources/Private/Extensions/News/Templates/
partialRootPath = EXT:mysitepackage/Resources/Private/Extensions/News/Partials/
layoutRootPath = EXT:mysitepackage/Resources/Private/Extensions/News/Layouts/
}
}
If needed, multiple fallbacks can be defined with TypoScript setup:
.. code-block:: typoscript
:caption: TypoScript setup
plugin.tx_news {
view {
templateRootPaths >
templateRootPaths {
0 = EXT:news/Resources/Private/Templates/
10 = EXT:mynewsextender/Resources/Private/Templates/
15 = EXT:myothernewsextender/Resources/Private/Templates/
20 = {$plugin.tx_news.view.templateRootPath}
}
partialRootPaths >
partialRootPaths {
0 = EXT:news/Resources/Private/Partials/
10 = EXT:mynewsextender/Resources/Private/Partials/
15 = EXT:myothernewsextender/Resources/Private/Partials/
20 = {$plugin.tx_news.view.partialRootPath}
}
layoutRootPaths >
layoutRootPaths {
0 = EXT:news/Resources/Private/Layouts/
10 = EXT:mynewsextender/Resources/Private/Layouts/
15 = EXT:myothernewsextender/Resources/Private/Layouts/
20 = {$plugin.tx_news.view.layoutRootPath}
}
}
}
It is recommended to always include the path from the TypoScript constants
last (with the highest numeral) so that the site package can still override
the templates.
Change path of the pagination widget
------------------------------------
The path of the pagination widget can be changed by using a configuration like below.
.. code-block:: typoscript
:caption: TypoScript setup
plugin.tx_news {
view {
widget.GeorgRinger\News\ViewHelpers\Widget\PaginateViewHelper {
templateRootPath = EXT:mysitepackage/Resources/Private/Extensions/News/Templates/
}
}
}
Layouts, templates & partials
=============================
If using Fluid, the templates are structured by using Layouts, templates and partials.
Layouts
-------
Layouts are used to structure the output of a plugin. A simple example is to
wrap every output with the same :html:`<div>` element. Therefore it is not
needed to repeat this code and write it only once.
A layout can look this:
.. code-block:: html
:caption: :file:`EXT:mysitepackage/Resources/Private/Extensions/News/Layouts/General.html`
<div class="myFancyNews">
<f:render section="content" />
</div>
This means that the output of the section :html:`content` will be rendered
inside a div with the class :html:`myFancyNews`.
Templates
---------
Every action (like the :guilabel:`List View`, the :guilabel:`Detail View`,
:guilabel:`Date Menu` or a :guilabel:`Category Listing`) needs its own
template which can be found at
:file:`EXT:news/Resources/Private/Templates/<Model>/<ActionName>.html`.
If :file:`Layouts` are used, it is required to define the name of the Layout
(which is identical to the file name of the layout file without file extension).
.. code-block:: html
:caption: :file:`mysitepackage/Resources/Private/Extensions/News/Templates/<Model>/<ActionName>.html`
<f:layout name="General" />
<f:section name="content">
This will be rendered
</f:section>
.. note::
It is optional to use layouts. If those are not used, the complete
content of the template is shown.
Partials
--------
Partials are used within templates to be able to reuse code snippets.
If you open the template :file:`Templates/News/List.html` you will see the
render ViewHelper:
.. code-block:: html
:caption: :file:`EXT:news/Resources/Private/Templates/News/List.html`
:linenos:
<f:render
partial="List/Item"
arguments="{
newsItem: newsItem,
settings: settings,
className: className,
view: 'list'
}"
/>
This will embed the output of the partial which is located at
:file:`Partials/List/Item.html` (attribute *partial*, line 2). All
arguments which are used in the attribute *arguments* (line 3ff)
are available in the partial itself.
You can override existing partials or create your own and name them as you like.
Sections
--------
Sections are very similar to partials. The difference is that sections
are defined in the same file as the template.
ViewHelpers
-----------
Every Fluid ViewHelper starts with :html:`<f:`. The view helpers supplied by
TYPO3 are documented in the :doc:`ViewHelper Reference <t3viewhelper:Index>`.
Any other ViewHelpers from other extensions can be used by using a
namespace declaration like
.. code-block:: html
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:n="http://typo3.org/ns/GeorgRinger/News/ViewHelpers"
xmlns:x="http://typo3.org/ns/Vendor/SomeExtension/ViewHelper"
data-namespace-typo3-fluid="true">
...
</html>
Then ViewHelpers of EXT:news can be used with prefix :html:`n:`. You can find
the available ViewHelpers in the chapter
:ref:`ViewHelper reference <viewHelpersReference>`.

View File

@@ -0,0 +1,82 @@
.. include:: /Includes.rst.txt
.. _templatesSelector:
=================
Template selector
=================
This entry should help you to use different templates for different (list) views.
Using the following Page TsConfig the editor can select the layouts in the news plugin:
.. code-block:: typoscript
tx_news.templateLayouts {
1 = A custom layout
99 = LLL:fileadmin/somelocallang/locallang.xlf:someTranslation
}
You can use any number to identify your layout and any label to describe it.
Now it is possible to use a condition in the template to change the layouts, and e.g. load a different partial:
.. code-block:: html
<f:if condition="{news}">
<f:then>
<f:if condition="{settings.templateLayout} == 99">
<f:then>
<div class="news well news-special">
<f:for each="{news}" as="newsItem">
<f:render partial="List/Item-special" arguments="{newsItem: newsItem, settings:settings}"/>
</f:for>
</div>
</f:then>
<f:else>
<div class="news news-list-view">
<f:for each="{news}" as="newsItem">
<f:render partial="List/Item-special" arguments="{newsItem: newsItem, settings:settings}"/>
</f:for>
</div>
</f:else>
</f:if>
</f:then>
<f:else>
<div class="no-news-found"><f:translate key="list_nonewsfound" /></div>
</f:else>
</f:if>
As you can see in this example a different partial is loaded if the layout 99 is used.
Custom Templates by using TypoScript
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
You can define a custom TypoScript setting which you can check in the view later on.
The TypoScript could look like:
.. code-block:: typoscript
plugin.tx_news {
settings {
isLatest = 1
}
}
And then you can use a condition like this:
.. code-block:: html
<f:if condition="{settings.isLatest}">
<f:then>
do something if it is set
</f:then>
<f:else>
do something if it is not set
</f:else>
</f:if>

View File

@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _templatesBootstrap:
===================
Bootstrap templates
===================
The following Twitter Bootstrap Template variants are available:
- v3
- v5
To be able to use it, include **additionally** the entry **News Styles Twitter Bootstrap** or **News Styles Twitter Bootstrap V5** in the section "Include Static (from extensions)" in the template record.
By changing the following constants, you can use those templates as base for your work.
.. code-block:: typoscript
# v5
plugin.tx_news {
view.twb5 {
templateRootPath = EXT:news/Resources/Private/Templates/Styles/Twb5/Templates
partialRootPath = EXT:news/Resources/Private/Templates/Styles/Twb5/Partials/
layoutRootPath = EXT:news/Resources/Private/Templates/Styles/Twb5/Layouts/
}
}
# v3
plugin.tx_news {
view.twb {
templateRootPath = EXT:news/Resources/Private/Templates/Styles/Twb/Templates
partialRootPath = EXT:news/Resources/Private/Templates/Styles/Twb/Partials/
layoutRootPath = EXT:news/Resources/Private/Templates/Styles/Twb/Layouts/
}
}

View File

@@ -0,0 +1,62 @@
.. include:: /Includes.rst.txt
.. _viewHelpersTutorial:
===========
ViewHelpers
===========
ViewHelpers are used to add logic inside the view.
There basic things like if/else conditions, loops and so on. The system
extension Fluid has the most important ViewHelpers already included.
To be able to use a ViewHelper in your template, you need to follow always the
same structure which is:
.. code-block:: html
<f:fo>bar</f:fo>
This would call the ViewHelper :code:`fo` of the namespace :code:`f` which stands for Fluid.
If you want to use ViewHelpers from other extensions you need to add the namespace
declaration at the beginning of the template. The namespace declaration for the news extension is:
.. code-block:: html
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:n="http://typo3.org/ns/GeorgRinger/News/ViewHelpers"
xmlns:x="http://typo3.org/ns/Vendor/Someextension/ViewHelper"
data-namespace-typo3-fluid="true">
...
</html>
Now you can use a ViewHelper of news with a code like:
.. code-block:: html
<n:headerData><!-- some comment --></n:headerData>
If you want to know what a ViewHelper does, it is very easy to find the related
PHP class by looking at the namespace and the name of the ViewHelper.
Having for example :php:`GeorgRinger\News\ViewHelpers` and :php:`headerData`
you will find the class at :file:`news\Classes\ViewHelpers\HeaderDataViewHelper.php`.
The most of awesome thing is that you can use ViewHelpers of any extension in
any other template by just adding another namespace declaration like:
.. code-block:: html
{namespace something=Tx_AnotherExtension_ViewHelpers}
and call the ViewHelper like
.. code-block:: html
<something:NameOfTheViewHelper />
See also
========
* :ref:`EXT:news ViewHelper reference <viewHelpersReference>`
* :ref:`Core ViewHelper reference <viewHelpersReference>`