TYPO3: How can I redirect to the translated homepage of a non translated page? - multilingual

I have created a multilanguage TYPO3 site with the following languages:
german (default)
english
spanish
There are no translations for all pages. For example I have ten pages in german and ten translated pages in english, but only four translated pages in spanish, but the language switcher is available on all sites. So if someone moves to one of the six pages which are not available in spanish and try to use the language switcher he will get the following error message:
Page Not Found
Reason: Page is not available in the requested language (strict).
This isn't really nice and I think a better solution is to redirect the user to the spanish homepage if there is no spanish translation of a specific page, but how can I do something like this?
My current language config looks like the following:
config {
...
sys_language_uid = 0
language = de
htmlTag_langKey = de-DE
locale_all = de_DE
sys_language_mode = strict
}
[globalVar = GP:L = 1]
config {
sys_language_uid = 1
language = en
htmlTag_langKey = en
locale_all = en_GB
linkVars = L(1)
}
[global]
[globalVar = GP:L = 2]
config {
sys_language_uid = 2
language = es
htmlTag_langKey = es
locale_all = es
linkVars = L(2)
}
[global]
And my language switcher looks like this:
obj.languageSwitcher = HMENU
obj.languageSwitcher {
special = language
special.value = 0,1,2
special.normalWhenNoLanguage = 0
1 = TMENU
1 {
NO = 1
NO {
doNotLinkIt = 1
stdWrap {
override = DE || EN || ES
typolink {
parameter.data = page:uid
additionalParams = &L=0 || &L=1 || &L=2
}
outerWrap = <li>|</li>
}
}
ACT < .NO
ACT {
stdWrap.typolink >
stdWrap.outerWrap = <li class="active">|</li>
}
USERDEF1 < .NO
USERDEF1 {
stdWrap.typolink >
}
}
}
As you can see I currently have defined a USERDEF1 which removes the link from my language switcher if there is no spanish version of the current site, but I still want to redirect the user to the homepage of the spanish version. Do you have any suggestions?

instead of removing the link you should change the target:
USERDEF1 < .NO
USERDEF1.stdWrap.typolink {
parameter.data >
parameter = 123 <- use your homepage id
}

Related

TYPO3 10 and Solr Extension - Search for partial Title not working

I am new to the Solr topic.
TYPO3 10.4.26
Solr-Ext 11.2.0
solr-spec 8.11.1
I have the following problem:
There is a file search by title, here it searches for "forklift" as an example. Solr then also finds files whose title contains "forklift" but not "forklifttest". Only if there is the whole word. It would be good if it is possible to search for "fork" and get "forklift" results.
How can I influence this? Maybe someone can help me.
Here you can see my index.queue settings for downloads. (Without additionalWhere because I do not think this will cause the problem)
I also tried _textNgramS = title but it doesn't seem to work
downloads = 1
downloads {
indexingPriority = 160
table = sys_file_metadata
additionalPageIds = 1,0
fields {
title = title
tabgroup_stringS = TEXT
tabgroup_stringS.value = downloads
size_intS = SOLR_RELATION
size_intS {
localField = file
foreignLabelField = size
}
fileExtension = SOLR_RELATION
fileExtension {
localField = file
foreignLabelField = extension
}
title_textS = SOLR_RELATION
title_textS {
localField = file
foreignLabelField = name
}
url_stringS = SOLR_RELATION
url_stringS {
localField = file
foreignLabelField = identifier
}
storageUid_intS = SOLR_RELATION
storageUid_intS {
localField = file
foreignLabelField = storage.uid
}
storage_stringS = SOLR_RELATION
storage_stringS {
localField = file
foreignLabelField = storage
}
category_stringM = SOLR_RELATION
category_stringM {
localField = categories
removeEmptyValues = 1
multiValue = 1
}
description = description
keywords = keywords
author = creator
}
}
I didn't make any changes to solr schema.xml or other solr stuff and hope i don't have to :D
If you need further informations let me know.

Typolink to index Pages on solr

I setup a TYPO3 v.9 website with solr.
And for some reason, the Pages indexer not working. So I used the custom TS configuration bellow, to work around and to force Pages indexing. With this custom TS, pages was indexed, BUT the links to a Page from the "Search results" is not working.
This is my custom TS :
#TS added to force page indexing
plugin.tx_solr.index.queue {
snar_pages = 1
snar_pages {
table = pages
fields {
title = title
content = SOLR_CONTENT
content {
cObject = COA
cObject {
10 = TEXT
10 {
field = bodytext
noTrimWrap = || |
}
}
}
url = CASE
url {
key.field = type
# Internal
1 = TEXT
1 {
if.isTrue.field = internalurl
typolink.parameter.field = internalurl
typolink.useCacheHash = 1
typolink.returnLast = url
}
# External
2 = TEXT
2 {
if.isTrue.field = externalurl
field = externalurl
}
default = TEXT
default {
typolink.parameter = {link}
typolink.additionalParams >
typolink.useCacheHash = 1
typolink.returnLast = url
}
}
}
}
is there an error in my TS that prevents the links to the pages from working ?
hmm i think you missed something to setup too for indexing pages. The DataFrontendHelper
see the docs
edited:
plugin.tx_solr {
index {
queue {
pages {
indexer {
frontendDataHelper {
host = {$plugin.tx_solr.indexer.frontendDataHandler.host}
scheme = {$plugin.tx_solr.indexer.frontendDataHandler.scheme}
}
}
}
}
}
}
Changing my TS as follows, and this fixed my problem :
url = CASE
url {
key.field = doktype
default = TEXT
default {
field = title
typolink.parameter.field = uid
typolink.returnLast = url
}
PS : pages need to be re-indexed for good results.

Copy DNN HTML Pro module in content to another module

Below code is working fine for HTML module but not working for HTML PRO module.
HtmlTextController htmlTextController = new HtmlTextController();
WorkflowStateController workflowStateController = new WorkflowStateController();
int workflowId = htmlTextController.GetWorkflow(ModuleId, TabId, PortalId).Value;
List<HtmlTextInfo> htmlContents = htmlTextController.GetAllHtmlText(ModuleModId);
htmlContents = htmlContents.OrderBy(c => c.Version).ToList();
foreach (var content in htmlContents)
{
HtmlTextInfo htmlContent = new HtmlTextInfo();
htmlContent.ItemID = -1;
htmlContent.StateID = workflowStateController.GetFirstWorkflowStateID(workflowId);
htmlContent.WorkflowID = workflowId;
htmlContent.ModuleID = ModuleId;
htmlContent.IsPublished = content.IsPublished;
htmlContent.Approved = content.Approved;
htmlContent.IsActive = content.IsActive;
htmlContent.Content = content.Content;
htmlContent.Summary = content.Summary;
htmlContent.Version = content.Version;
}
htmlTextController.UpdateHtmlText(htmlContent, htmlTextController.GetMaximumVersionHistory(PortalId));
This is occurred due to HTML Pro module has different methods. That is partially different from DNN HTML Module. below is the code.
HtmlTextController htmlTextController = new HtmlTextController();
WorkflowStateController workflowStateController = new WorkflowStateController();
WorkflowStateInfo wsinfo = new WorkflowStateInfo();
int workflowId = wsinfo.WorkflowID;
HtmlTextInfo htmlContents = htmlTextController.GetLatestHTMLContent(ModuleModId);
HtmlTextInfo htmlContent = new HtmlTextInfo();
htmlContent.ItemID = -1;
htmlContent.StateID = workflowStateController.GetFirstWorkflowStateID(workflowId);
htmlContent.WorkflowID = workflowId;
htmlContent.ModuleID = ModuleId;
htmlContent.IsPublished = htmlContents.IsPublished;
htmlContent.Approved = htmlContents.Approved;
htmlContent.IsActive = htmlContents.IsActive;
htmlContent.Content = htmlContents.Content;
htmlContent.Summary = htmlContents.Summary;
htmlContent.Version = htmlContents.Version;
if (Tags != null && Tags.Count > 0)
{
foreach (KeyValuePair<string, string> tag in Tags)
{
if (htmlContent.Content.Contains(tag.Key))
{
htmlContent.Content = htmlContent.Content.Replace(tag.Key, tag.Value);
}
}
}
htmlTextController.SaveHtmlContent(htmlContent, newModule);
And please add below reference to the code to refer the methods.
using DotNetNuke.Modules.HtmlPro;
using DotNetNuke.Professional.HtmlPro;
using DotNetNuke.Professional.HtmlPro.Components;
using DotNetNuke.Professional.HtmlPro.Services;
If you are looking to simply "copy" the content from one to the other, you might investigate the usage of the "Import" and "Export" functions that are part of these modules.
I recommend using this route to help you ensure better compatibility as time progresses. Should they update fields or other data elements you will not have to investigate and then update your code as part of this.
You can simply look at the .dnn manifest for each of these modules and find the BusinessControllerClass which will have two methods "ImportModule" and "ExportModule" that you could use.

Why Typo3 website special characters are not saving to database?

I got a website to move to our server and I have successfully moved it.But I have noticed some strange thing.Site doesn't render Danish characters (only special characters).When when I try to save using htmlarea in admin section and I can save Lorem Ipsum with any issue.But special danish characters are seems saving to database but when I open htmlarea it shows nothing.
Seems me there should be some configuration or settings to do.I tried to change character set but didnt work.Then whole db and table change to Utf8.No luck.
Anyone is having an idea to fix this?
please mentioned the place and page name as I am totally newbie to typo3
Thanks
More info regarding typo3 ond utf8 you can find there - http://wiki.typo3.org/UTF-8_support (TYPO3 UTF-8 support). Which TYPO3 version you have?
I think you have to modify your page typoscript configuration.
set htmlSpecialChars = 0 at the time of both entryHTMLparser_db and exitHTMLparser_db.
Use below page typoscript configuration. Might be your problem will be solved.
mod.SHARED {
defaultLanguageFlag = de
defaultLanguageLabel = Deutsch
}
# Classes. Do not forget to define them in the CSS class
RTE.classes {
# lists
checklist {
name = Checkliste
}
# tables
table {
name = Normale Tabelle
}
table-condensed {
name = Verkürzte Tabelle
}
table-bordered {
name = Tabelle mit Rahmen
}
table-styled {
name = Tabelle mit anderem Design
}
table-striped {
name = Tabelle mit Streifen
}
table-hover {
name = Tabelle mit Hover-Effekt
}
# aligns
align-justify {
name = LLL:EXT:rtehtmlarea/htmlarea/locallang_tooltips.xml:justifyfull
}
align-left {
name = LLL:EXT:rtehtmlarea/htmlarea/locallang_tooltips.xml:justifyleft
value = text-align: left;
}
align-center {
name = LLL:EXT:rtehtmlarea/htmlarea/locallang_tooltips.xml:justifycenter
value = text-align: center;
}
align-right {
name = LLL:EXT:rtehtmlarea/htmlarea/locallang_tooltips.xml:justifyright
value = text-align: right;
}
csc-frame-frame1 {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:frame-frame1
value = background-color: #EDEBF1; border: 1px solid #333333;
}
csc-frame-frame2 {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:frame-frame2
value = background-color: #F5FFAA; border: 1px solid #333333;
}
important {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:important
value = color: #8A0020;
}
name-of-person {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:name-of-person
value = color: #10007B;
}
detail {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:detail
value = color: #186900;
}
component-items {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:component-items
value = color: #186900;
}
action-items {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:action-items
value = color: #8A0020;
}
component-items-ordered {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:component-items
value = color: #186900;
}
action-items-ordered {
name = LLL:EXT:rtehtmlarea/res/contentcss/locallang.xml:action-items
value = color: #8A0020;
}
style1 {
name = Stil 1
}
htmlCode {
name = HTML Code
}
phpCode {
name = PHP Code
}
}
RTE.classesAnchor {
externalLink {
class = external-link
type = url
titleText = LLL:EXT:rtehtmlarea/res/accessibilityicons/locallang.xml:external_link_titleText
}
externalLinkInNewWindow {
class = external-link-new-window
type = url
titleText = LLL:EXT:rtehtmlarea/res/accessibilityicons/locallang.xml:external_link_new_window_titleText
}
internalLink {
class = internal-link
type = page
titleText = LLL:EXT:rtehtmlarea/res/accessibilityicons/locallang.xml:internal_link_titleText
}
internalLinkInNewWindow {
class = internal-link-new-window
type = page
titleText = LLL:EXT:rtehtmlarea/res/accessibilityicons/locallang.xml:internal_link_new_window_titleText
}
download {
class = download
type = file
titleText = LLL:EXT:rtehtmlarea/res/accessibilityicons/locallang.xml:download_titleText
}
mail {
class = mail
type = mail
titleText = LLL:EXT:rtehtmlarea/res/accessibilityicons/locallang.xml:mail_titleText
}
more-link {
class = more-link
type = page
titleText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:more_link_titleText
altText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:more_link_altText
}
button-link {
class = btn
type = page
titleText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:more_link_titleText
altText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:more_link_altText
}
next-link {
class = ym-button ym-next
type = page
titleText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:next_link_titleText
altText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:next_link_altText
}
back-link {
class = back-link
type = page
titleText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:back_link_titleText
altText = LLL:EXT:fluxtemplate/Resources/Private/Language/locallang.xml:back_link_altText
}
}
RTE.default {
showButtons = *
## Enable the image button
showButtons := addToList(image)
defaultContentLanguage = de
// Make possible to read classes from the contentCSS CSS file
buttons.textstyle.tags.span.allowedClasses >
buttons.textstyle.tags.REInlineTags >
buttons.textstyle.REInlineTags >
buttons.blockstyle.tags.table.allowedClasses >
buttons.blockstyle.tags.p.allowedClasses >
buttons.blockstyle.tags.div.allowedClasses = align-left, align-center, align-right
buttons.blockstyle.tags.div.allowedClasses := addToList(csc-frame-frame1, csc-frame-frame2)
buttons.blockstyle.tags.table.allowedClasses = csc-frame-frame1, csc-frame-frame2
buttons.blockstyle.tags.td.allowedClasses = align-left, align-center, align-right
buttons.textstyle.tags.span.allowedClasses = important, name-of-person, detail
contentCSS = typo3conf/ext/fluxtemplate/Resources/Public/CSS/rte.css
buttons.formatblock.prefixLabelWithTag = 1
buttons.link.relAttribute.enabled = 1
buttons.link.queryParametersSelector.enabled = 1
buttons.link.properties.class.allowedClasses = external-link, external-link-new-window, internal-link, internal-link-new-window, download, mail
buttons.link.page.properties.class.default = internal-link
buttons.link.url.properties.class.default = external-link-new-window
buttons.link.file.properties.class.default = download
buttons.link.mail.properties.class.default = mail
buttons.image.properties.class.allowedClasses = img-responsive
// Disable contextual menu
contextMenu.disabled = 1
// Display status bar
showStatusBar = 1
//More toolbar options
keepButtonGroupTogether = 1
// Use CSS formatting when possible
useCSS = 1
// Make rtehtmlarea resizable
rteResize = 1
proc {
allowedClasses = external-link, external-link-new-window, internal-link, internal-link-new-window, download, mail
allowedClasses := addToList(detail,align-left, align-center, align-right, align-justify, csc-frame-frame1, csc-frame-frame2, component-items, action-items, component-items-ordered, action-items-ordered, important, name-of-person, indent, img-responsive)
allowedClasses < RTE.default.classesCharacter
# auskommentieren, damit klassen eingelesen werden können
#allowedClasses := addToList( dimmed,highlight,box,info,success,warning,error,float-left,float-right,center,align-left,align-center,align-right,align-justify,style1 )
## TAGS ALLOWED OUTSIDE P & DIV
allowTagsOutside := addToList( pre, img )
allowTags := addToList( pre )
// Tags allowed in Typolists
allowTagsInTypolists = br,font,b,i,u,a,img,span
// Keep unknown tags
dontRemoveUnknownTags_db = 1
// Allow tables
preserveTables = 1
entryHTMLparser_db = 1
entryHTMLparser_db {
// Tags allowed
allowTags < RTE.default.proc.allowTags
// Tags denied
denyTags >
// HTML special characters
htmlSpecialChars = 0
// Allow IMG tags
tags.img >
// Additionnal attributes for P & DIV
tags.div.allowedAttribs = class,style,align
tags.p.allowedAttribs = class,style,align
// Tags to remove
removeTags = center, font, o:p, sdfield, strike, u
// Keep non matched tags
keepNonMatchedTags = protect
}
// HTML parser
HTMLparser_db {
// Strip attributes
noAttrib = br
// XHTML compliance
xhtml_cleaning = 1
}
// Exit HTML parser
exitHTMLparser_db = 1
exitHTMLparser_db {
// Remap bold and italic
tags.b.remap = strong
tags.i.remap = em
// Keep non matched tags
keepNonMatchedTags = 1
// HTML special character
htmlSpecialChars = 0
}
}
}
RTE.default.FE < RTE.default
RTE.default.FE.showButtons < RTE.default.showButtons
RTE.default.FE.proc.allowTagsOutside < RTE.default.proc.allowTagsOutside
RTE.default.FE.proc.entryHTMLparser_db.tags.img >
// PageTSConfig
TCEFORM.tt_content.header_layout.altLabels {
0 = H1 (Default)
1 = H1
2 = H2
3 = H3
4 = H4
5 = H5
}
I also have same problem in my another project.
First set default_charset to utf8 in your php.ini file.
or you can manuaaly set it with below PHP code:
ini_set('default_charset', 'utf8');

TYPO3 Formhandler finisher does not write to database

After the TYPO3 (6.1.7) website of a customer has gone online, the Formhandler forms do not work correctly anymore. They do send an email, but it seems that they do not execute the Finisher_DB for writing into the database anymore.
The TypoScript settings look like this:
plugin.Tx_Formhandler.settings {
debug = 0
# GENERAL CONFIGURATION
name = Default
addErrorAnchors = 1
formValuesPrefix = formhandler
fillValueMarkersBeforeLangMarkers = 1
# ERRORS LAYOUT
singleErrorTemplate {
totalWrap = <div>|</div>
singleWrap = <span class="error">|</span><br />
}
errorListTemplate {
totalWrap = <ul>|</ul>
singleWrap = <li class="error">|</li>
}
validators {
1.class = Tx_Formhandler_Validator_Default
1.config {
fieldConf {
wish.errorCheck.1 = required
alternative.errorCheck.1 = required
firstname.errorCheck.1 = required
surname.errorCheck.1 = required
nationality.errorCheck.1 = required
dateofbirth.errorCheck.1 = required
phone.errorCheck.1 = required
email.errorCheck.1 = required
street.errorCheck.1 = required
zip.errorCheck.1 = required
city.errorCheck.1 = required
country.errorCheck.1 = required
}
}
}
# Finishers configuration
finishers {
1.class = Tx_Formhandler_Finisher_Mail
1.config {
checkBinaryCrLf = registrationMessagePlain, registrationMessageHtml
limitMailsToUser = 10
admin {
}
user {
}
}
2.class = Tx_Formhandler_Finisher_DB
2.config{
table = tx_chilifhregistration
key = uid
fields {
timeslot = Sommerplatz
timeslot_july.mapping = timeslotSummerJuly
timeslot_august.mapping = timeslotSummerAugust
timeslot_september.mapping = timeslotSummerSeptember
wish.mapping = wish
wishcategory11.mapping = wishCategory11
wishcategory19.mapping = wishCategory19
wishcategory22.mapping = wishCategory22
wishcategorydb.mapping = wishCategoryDb
alternative.mapping = alternative
alternativecategory11.mapping = alternativeCategory11
alternativecategory19.mapping = alternativeCategory19
alternativecategory22.mapping = alternativeCategory22
alternativecategorydb.mapping = alternativeCategoryDb
salutation.mapping = salutation
firstname.mapping = firstname
surname.mapping = surname
nationality.mapping = nationality
dateofbirth.mapping = dateofbirth
phone.mapping = phone
email.mapping = email
street.mapping = street
zip.mapping = zip
city.mapping = city
country.mapping = country
salutation2.mapping = salutation2
firstname2.mapping = firstname2
surname2.mapping = surname2
nationality2.mapping = nationality2
dateofbirth2.mapping = dateofbirth2
phone2.mapping = phone2
email2.mapping = email2
street2.mapping = street2
zip2.mapping = zip2
city2.mapping = city2
country2.mapping = country2
}
}
}
}
What could be the problem?
You should better use the predef-definition-style for forms. This will save you trouble with multiple forms and is a cleaner implementation.
plugin.Tx_Formhandler.settings.predef.yourformularname { ...config... }
You can find a bunch of examples on the offical site/examples
I assume that your admin and user mail-config is only empty because you won´t post any customerinformation?
Did the form work if you fill in every single field?
In my own usecases all field i map with the finisher are required, maybe you should set a ...IfEmpty-option for non-require fields.
Here are the available ifEmpty-options.

Resources