Initial commit - Typo3 11.5.41
This commit is contained in:
@@ -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.
|
||||
@@ -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>`.
|
||||
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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`.
|
||||
@@ -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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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&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]=|
|
||||
}
|
||||
}
|
||||
@@ -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`.
|
||||
@@ -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>`.
|
||||
|
||||
@@ -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>`.
|
||||
|
||||
@@ -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>`__
|
||||
@@ -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 =
|
||||
replace =  
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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>`.
|
||||
@@ -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>`.
|
||||
@@ -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>`.
|
||||
@@ -0,0 +1,15 @@
|
||||
.. include:: /Includes.rst.txt
|
||||
|
||||
.. _dataProcessing:
|
||||
|
||||
===============
|
||||
Data processing
|
||||
===============
|
||||
|
||||
The extension news currently contains the following data processors:
|
||||
|
||||
.. toctree::
|
||||
:titlesonly:
|
||||
|
||||
AddNewsToMenuProcessor
|
||||
LanguageMenuProcessor
|
||||
@@ -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>`.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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>`.
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
|
||||
121
typo3conf/ext/news/Documentation/Tutorials/ExtendNews/Index.rst
Normal file
121
typo3conf/ext/news/Documentation/Tutorials/ExtendNews/Index.rst
Normal 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
|
||||
@@ -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`.
|
||||
|
||||
@@ -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.
|
||||
69
typo3conf/ext/news/Documentation/Tutorials/Index.rst
Normal file
69
typo3conf/ext/news/Documentation/Tutorials/Index.rst
Normal 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
|
||||
@@ -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.
|
||||
135
typo3conf/ext/news/Documentation/Tutorials/Templates/Index.rst
Normal file
135
typo3conf/ext/news/Documentation/Tutorials/Templates/Index.rst
Normal 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
|
||||
@@ -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>
|
||||
@@ -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.
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>`.
|
||||
@@ -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>
|
||||
|
||||
|
||||
|
||||
@@ -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/
|
||||
}
|
||||
}
|
||||
@@ -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>`
|
||||
Reference in New Issue
Block a user