Newly added translation is not shown - internationalization

On a Typo3 4.4.2 with existing translations I wanted to add a new one. But the text element is only displayed on the default language and not on the English page. Then I tried to add a content element on the English page. Here it will be shown but only in English. It seems that the translations are completely separated from each other ...
Here is the TS:
config {
linkVars = L
sys_language_mode = content_fallback
sys_language_overlay = hideNonTranslated
sys_language_uid =
language = de
locale_all = de_DE
doctype = xhtml_trans
htmlTag_langKey = de
}
[globalVar = GP:L = 1]
config.sys_language_uid = 1
page.config.language = en
page.config.locale_all = en_EN
[global]
What is here wrong? Deleting the cache had no success so it is another problem.

Please use the "Copy default content elements" option for translating default content elements to English language.

Make sure to translate the page with the content element too. Otherwise the content element can not be saved.
If the mapping between the translation is lost, then you have to fix this in the database or with the extension languagevisibility.

Related

Bibiliography style with Quarto documents

The default way of displaying references with Quarto documents seems to put author names in this format: Last1, First1, First2 Last2, First3 Last3, and First4 Last4. So the first author name is displayed differently than the rest. Is that intentional and is there a way to change that?
Here's an example:
---
project:
type: website
format: html
bibliography: references.bib
---
## Text
#bibitem1
Content of references.bib
#article{bibitem1,
author = {First1 Last1 and First2 Last2 and First3 Last3 and First4 Last4},
title = {Article title},
journal = {Journal name},
year = {2013},
volume = {3},
number = {72},
pages = {14--18}
}
which is displayed as
Last1, First1, First2 Last2, First3 Last3, and First4 Last4. 2013. “Article Title.” Journal Name 3 (72): 14–18.
How your references are displayed is entirely determined by the bibliography format you use. Quarto adopts a default one. You can specify a custom one with the csl option, specified in your YAML header as for example:
csl: biomed-central.csl
Styles for many journals are available with the Zotero project: https://www.zotero.org/styles
These styles are composed using the Citation Style Language. In principle, you could customize such a style (including the default style used by Quarto). It is not that trivial, though, and would require some effort to understand and use the language.

Reactivity conundrum in shiny; dynamically translating text going into selectInput()

I am working on a multilingual shiny app using the shiny.i18n package to translate different parts of the UI. It works really well until I tried to dynamically translate the text inside a specific selectInput menu. Some reproducible code below:
# Translating text of a menu item from data
library(shiny)
library(shiny.i18n)
library(tidyverse)
# Create translation file and save in a directory called trans
system("mkdir trans")
translation_key <- data.frame(es = c("Cambiar de lenguaje", "Seleccione un proyecto", "Todos"),
en = c("Change language", "Select a project", "All")
)
write.csv(translation_key, "trans/translation_key.csv",
row.names = FALSE,
quote = FALSE)
# Create data object
data <- data.frame(project_name =c("Todos","proj1", "proj2"),
n = c(20,30,40)
)
# Setup translator
trans <- Translator$new(translation_csvs_path = "trans")
trans$set_translation_language("es")
# Define UI
ui <- fluidPage(
usei18n(trans),
# Application title
titlePanel("Reactivity test"),
mainPanel(
selectInput('selected_language',
trans$t("Cambiar de lenguaje"),
choices = trans$get_languages()
),
selectInput("project_name",
trans$t("Seleccione un proyecto"),
choices = NULL
),
textOutput("n")
)
)
# server part
server <- function(session, input, output) {
# update languae
observeEvent(input$selected_language, {
update_lang(session, input$selected_language)
print(paste("Language change!", input$selected_language))
})
# change the first element of data$project and translate it! It does not do it!
data_rv <- eventReactive(input$selected_language, {
data$project_name[1] <- trans$t("Todos")
data
})
# update the selection for project name depending on the language
observeEvent(data_rv(), {
updateSelectInput(session, inputId = "project_name",
choices = unique(data_rv()$project_name))
})
# print the n associated with project_name selected
output$n <- renderText({
req(input$project_name)
res <- data_rv() %>% filter(project_name == input$project_name)
res$n
})
}
# Run the application
shinyApp(ui = ui, server = server)
I attempt the translation of the first element of data$project_name inside an eventReactive call that returns the modified translated object. The problem is that the translation does not happen until after the menu for project_name is rendered (see screenshot below).
The application starts by default in Spanish (es) and when changed to English (en), everything is translated except the first item in the Select a project menu (it should say All instead of Todos).
I have found a solution using uiOutput and renderUI but the application I am working on has a very complex layout of panels and tabs and I rather not rework all the code if I can help it. Can someone recommend a workaround that works from the browser side. Thanks,
An alternative in this case could be making data_rv a reactive expression with a req() instead of an eventReactive. It may also keep it simple for your purpose.
I tried it like this with your example:
# change the first element of data$project and translate it!
data_rv <- reactive({
req(input$selected_language)
data$project_name[1] <- trans$t(data$project_name[1])
data
})
Seems it checks out!
reactivity question image here
Note: I translated reactivity test to prueba de reactividad for clarity but is not in the original reproducible example

how to get value of a tag that has no class or id in html agility pack?

I am trying to get the text value of this a tag:
67 comments
so i'm trying to get '67' from this. however there are no defining classes or id's.
i've managed to get this far:
IEnumerable<HtmlNode> commentsNode = htmlDoc.DocumentNode.Descendants(0).Where(n => n.HasClass("subtext"));
var storyComments = commentsNode.Select(n =>
n.SelectSingleNode("//a[3]")).ToList();
this only give me "comments" annoyingly enough.
I can't use the href id as there are many of these items, so i cant hardcord the href
how can i extract the number aswell?
Just use the #href attribute and a dedicated string function :
substring-before(//a[#href="item?id=22513425"],"comments")
returns 67.
EDIT : Since you can't hardcode all the content of #href, maybe you can use starts-with. XPath 1.0 solution.
Shortest form (+ text has to contain "comments") :
substring-before(//a[starts-with(#href,"item?") and text()[contains(.,"comments")]],"c")
More restrictive (+ text has to finish with "comments") :
substring-before(//a[starts-with(#href,"item?")][substring(//a, string-length(//a) - string-length('comments')+1) = 'comments'],"c")
I am using ScrapySharp nuget which adds in my sample below, (It's possible HtmlAgilityPack offers the same functionality built it, I am just used to ScrapySharp from years ago)
var doc = new HtmlDocument();
doc.Load(#"C:\desktop\anchor.html"); //I created an html file with your <a> element as the body
var anchor = doc.DocumentNode.CssSelect("a").FirstOrDefault();
if (anchor == null) return;
var digits = anchor.InnerText.ToCharArray().Where(c => Char.IsDigit(c));
Console.WriteLine($"anchor text: {anchor.InnerText} - digits only: {new string(digits.ToArray())}");
Output:

HtmlAgilityPack sanitizing string issue

I'm using HtmlAgilityPack to sanitize user entered rich text and strip any harmful/unwanted text. Problem occurs though when a simple text is also treated as html node
If I enter
a<b, c>d
and try to sanitize it, the output generated is
a<b, c="">d</b,>
The code I used was
HtmlDocument doc = new HthmlDocument();
doc.LoadHtml(value);
// Sanitizing Logic
var result = doc.DocumentNode.WriteTo();
I tried to set different parameters on HtmlDocument ('OptionCheckSyntax', 'OptionAutoCloseOnEnd', 'OptionWriteEmptyNodes') to not have the text be treated as a node but nothing worked. Is this is a known issue or any workaround possible?
IMO, there's no way you can tell HAP to not treat every '<' as start of new html node. But you can check if your html is a validate html or not by using
string html = "your-html";
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
if (doc.ParseErrors.Count() > 0)
{
//here you can ignore or do whatever you want
}

Read image IPTC data

I'm having some trouble with reading out the IPTC data of some images, the reason why I want to do this, is because my client has all the keywords already in the IPTC data and doesn't want to re-enter them on the site.
So I created this simple script to read them out:
$size = getimagesize($image, $info);
if(isset($info['APP13'])) {
$iptc = iptcparse($info['APP13']);
print '<pre>';
var_dump($iptc['2#025']);
print '</pre>';
}
This works perfectly in most cases, but it's having trouble with some images.
Notice: Undefined index: 2#025
While I can clearly see the keywords in photoshop.
Are there any decent small libraries that could read the keywords in every image? Or am I doing something wrong here?
I've seen a lot of weird IPTC problems. Could be that you have 2 APP13 segments. I noticed that, for some reasons, some JPEGs have multiple IPTC blocks. It's possibly the problem with using several photo-editing programs or some manual file manipulation.
Could be that PHP is trying to read the empty APP13 or even embedded "thumbnail metadata".
Could be also problem with segments lenght - APP13 or 8BIM have lenght marker bytes that might have wrong values.
Try HEX editor and check the file "manually".
I have found that IPTC is almost always embedded as xml using the XMP format, and is often not in the APP13 slot. You can sometimes get the IPTC info by using iptcparse($info['APP1']), but the most reliable way to get it without a third party library is to simply search through the image file from the relevant xml string (I got this from another answer, but I haven't been able to find it, otherwise I would link!):
The xml for the keywords always has the form "<dc:subject>...<rdf:Seq><rdf:li>Keyword 1</rdf:li><rdf:li>Keyword 2</rdf:li>...<rdf:li>Keyword N</rdf:li></rdf:Seq>...</dc:subject>"
So you can just get the file as a string using file_get_contents(get_attached_file($attachment_id)), use strpos() to find each opening (<rdf:li>) and closing (</rdf:li>) XML tag, and grab the keyword between them using substr().
The following snippet works for all jpegs I have tested it on. It will fill the array $keys with IPTC tags taken from an image on wordpress with id $attachment_id:
$content = file_get_contents(get_attached_file($attachment_id));
// Look for xmp data: xml tag "dc:subject" is where keywords are stored
$xmp_data_start = strpos($content, '<dc:subject>') + 12;
// Only proceed if able to find dc:subject tag
if ($xmp_data_start != FALSE) {
$xmp_data_end = strpos($content, '</dc:subject>');
$xmp_data_length = $xmp_data_end - $xmp_data_start;
$xmp_data = substr($content, $xmp_data_start, $xmp_data_length);
// Look for tag "rdf:Seq" where individual keywords are listed
$key_data_start = strpos($xmp_data, '<rdf:Seq>') + 9;
// Only proceed if able to find rdf:Seq tag
if ($key_data_start != FALSE) {
$key_data_end = strpos($xmp_data, '</rdf:Seq>');
$key_data_length = $key_data_end - $key_data_start;
$key_data = substr($xmp_data, $key_data_start, $key_data_length);
// $ctr will track position of each <rdf:li> tag, starting with first
$ctr = strpos($key_data, '<rdf:li>');
// Initialize empty array to store keywords
$keys = Array();
// While loop stores each keyword and searches for next xml keyword tag
while($ctr != FALSE && $ctr < $key_data_length) {
// Skip past the tag to get the keyword itself
$key_begin = $ctr + 8;
// Keyword ends where closing tag begins
$key_end = strpos($key_data, '</rdf:li>', $key_begin);
// Make sure keyword has a closing tag
if ($key_end == FALSE) break;
// Make sure keyword is not too long (not sure what WP can handle)
$key_length = $key_end - $key_begin;
$key_length = (100 < $key_length ? 100 : $key_length);
// Add keyword to keyword array
array_push($keys, substr($key_data, $key_begin, $key_length));
// Find next keyword open tag
$ctr = strpos($key_data, '<rdf:li>', $key_end);
}
}
}
I have this implemented in a plugin to put IPTC keywords into WP's "Description" field, which you can find here.
ExifTool is very robust if you can shell out to that (from PHP it looks like?)

Resources