Determine active Page Object within Typo3 - typo3

I'm writing a plugin which should add HTML to the page's head area (inludeJS to be exact). Something like this should work:
page.includeJS {
tx_myplugin_pi1 = EXT:my_plugin/pi1/tx_myplugin_fe_scripts.js
}
The problem with that is that I have to assume that "page" would be the universal name used for the page object I want to work with. Since the name of this variable can be anything I would like to do this in a more intelligent way than this.
Is there a way to determine the name of the current PAGE cObject I'm working with?
cu
Roman

You can find out the default PAGE object of the current page using this snippet:
$setup = $GLOBALS['TSFE']->tmpl->setup;
foreach(array_keys($setup) as $key){
if(substr($key, -1) == '.'){
if($setup[substr($key,0,-1)] === 'PAGE' && intval($setup[$key]['typeNum']) === 0){
print substr($key,0,-1) .' is the default PAGE object';
}
}
}
But this won't help you to add the Javascript in the frontend, as the typoscript is being parsed already at that point.
If you want to add the javascript just for your extension I would recommend using:
$GLOBALS['TSFE']->additionalHeaderData['tx_yourextension_plugin'] = '<script type="text/javascript" src="' . t3lib_extMgm::siteRelPath('my_plugin') . 'pi1/tx_myplugin_fe_scripts.js"></script>';
(this wouldn't be merged with the other JS files though)

Actually there is no such way in plain TypoScript. As most installations are using page as keyword - especially those which are under your control - it is really fine to use it.
If you are writing an extension, you can put that into the documentation as a small hint!

Related

eliminate inline <script> in file generated by doxygen

A proposed change to the Content Security Policy (CSP) of our web server to disallow inline script
is causing a problem with the documentation generated by doxygen. Specifically, the problem occurs
in the generated index.html file, and the following lines:
<!-- Generated by Doxygen 1.8.15 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* #license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
$(function() {
initMenu('',false,false,'search.php','Search');
})
/* #license-end */</script>
If the initMenu() code is put into a separate file that is just included like other JavaScript files, everything
works just fine. Is there a doxygen option to put all JavaScript into files rather that inline? We can
post process the generated file to do this, but may not know when the "pattern" of this code may
change due to updates in doxygen itself. And we may not know if using additional doxygen features will result in other inline JavaScript.
Any suggestions would be welcome.
Thank you
Fritz Sieker
First off Content Security Policy is useful but far from being an absolute authority. There are other completely useless headers such as those that block referrers based on "privacy".
Secondly there is no such thing as "text/javascript", perhaps they meant application/javascript?
If you're using good (though very non-common practices) you don't have any script elements in the body element (use defer="true" on script elements in the head). By doing that you'll better understand the structure of JavaScript and that in turn will help you become more proficient/capable/help more people/make more money/etc.
You can use document.getElementsByTagName('body')[0].getElementsByTagName('script') to find all the script elements in the body element that don't belong there.
If you do have script elements in the body element beforehand and moving them to the head element is not feasible right now you're likely going to have to work with inherent logic, in short those script elements will always be inserted in to the DOM in a specific and reasonably easily reproducible area of your code (like as the very last elements). In such a case you can find them via the following:
document.getElementsByTagName('body')[0].lastChild
document.getElementsByTagName('body')[0].lastChild.previousSibling
document.getElementsByTagName('body')[0].lastChild.previousSibling.previousSibling
Keep in mind that pressing Enter in your code to make it more readable will insert a textNode so you may want to append nodeName to those instances and look for "script":
console.log(document.getElementsByTagName('body')[0].lastChild.nodeName);
There is the DOM TreeWalker that might help you out here, subjective to the end result in your DOM. I don't know offhand if you can transverse all the elements in reverse (probably).
Once you know what you want to delete instead of making everything convoluted just send that object (or id) to the following:
function element_del(id)
{
if (typeof id=='string' && id_(id) && id_(id).parentNode.removeChild)
{
id_(id).parentNode.removeChild(id_(id));
}
else if (typeof id=='object' && typeof id.parentNode=='object') {id.parentNode.removeChild(id);}
}
//Example:
element_del(document.getElementsByTagName('body')[0].lastChild);
I hope this helps!

Custom tags in TYPO3 content

new here, and also new to TYPO3.
I need to put something like [imagebox, title='box1'] into content editor and that will be replaced by a text and image with some javascript effect (text and image are managed in the DB elsewhere, the tag is just for the placement in the page).
I've read that TYPO3 has a mechanism for adding custom tags and I managed to make them accepted in the RTE.
I tried instead of [imagebox..... to use
<imagebox>box1</imagebox>
with something like this (copied from web):
tt_content.text.20.parseFunc.tags {
imagebox < lib.parseFunc.tags.link
imagebox = TEXT
imagebox.value= replaced
# imagebox = PHP_SCRIPT
# imagebox {
# stripNL = 0
# Pass a parameter from Typoscript to a PHP script:
# UID of the page containing the SINGLE view of tt_news
# id_singleView = 18
# Call the PHP script
# file = fileadmin/scripts/imagebox_parser.php
# }
}
lib.parseFunc.tags.imagebox < tt_content.text.20.parseFunc.tags.imagebox
should be able to replace content between tags.
I've commented call to php function just tried to get a text replacement for starters.
I've put that in the main root template Setup, but nothing is replaced.
I've also tried other examples from the web with no success.
Did anyone have situation like this?
Are there better approaches for that in TYPO3? (I'm using v7.6.23)
Any suggestion or hint is appreciated.
EDIT: using FSC on textmedia element
I think your examples are outdated. (the object PHP_SCRIPT is obsolete for a long time)
You might have a look at the documentation for your TYPO3 version:
https://docs.typo3.org/typo3cms/TyposcriptReference/7.6/Functions/Parsefunc/
you also need to enhance the parsefunc where you need it. That can depend on:
CSC or FSC?
which kind of content element (CE) do you use? (be sure to enhance the rendering of that CE)

Can't add javascript to rich text editor

I'm trying to allow javascript in rich text editor inputs in my Umbraco setup. I'm using Umbraco 7.2. I've enabled the script tag in tinyMceConfig.config so the editor no longer eats my script tags. The problem now is that my content is cut off.
For example, in my RTE I put:
<p>before</p>
<script>
alert('blam');
</script>
<p>after</p>
This get's transformed by TinyMCE to:
<p>before</p>
<script>// <![CDATA[
alert('blam');
// ]]></script>
<p>after</p>
The problem is the value of Umbraco.Field("myRte") ends up being:
<p>before</p>
<script>// <![CDATA[
alert('blam');
// ]]
It seems related to CDATA. Does anyone else have javascript in RTE working in Umbraco 7?
A possible workaround would be to create a macro that would allow you to insert a script into the RTE. The macro would have a single Textarea parameter where you would paste in your script tag, and you would simply render the parameter value as raw Html. However, it might be a good idea to check that the input is valid html before you attempt to render it on the page.
If you use a razor macro the partial view could look like this:
#inherits Umbraco.Web.Macros.PartialViewMacroPage
#{
var script = Model.MacroParameters["script"].ToString();
}
#if (!script.IsNullOrWhiteSpace())
{
#Html.ValidateHtml(script)
}
Where ValidateHtml is an extension method to the Mvc HtmlHelper:
public static IHtmlString ValidateHtml(this HtmlHelper helper, string input)
{
if (!string.IsNullOrEmpty(input))
{
var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(input);
if (htmlDoc.ParseErrors.Count() == 0)
{
return new MvcHtmlString(input);
}
}
return null;
}
The helper method uses the Html Agility Pack and I got the code from an answer posted to another SO question.
I've tested this on an Umbraco 7.2.1 install and it works fine even if you select the "Render in rich text editor and the grid" option.
My solution is not write direct script in editor, write it in a test.js file after that include
<script src="https:/....test.js></script>
In tiniMceConfig.config file (config folder)
validElements tag, add this
,script[type|src|language]
so it will look like this
<![CDATA[+a[id|style|rel
.....
,bdo,button,script[type|src|language]]]>
Test and work on Umbraco 4.7.x. I'm not test on umbraco 7

CKEditor automatically strips classes from div

I am using CKEditor as a back end editor on my website. It is driving me round the bend though as it seems to want to change the code to how it sees fit whenever I press the source button. For example if I hit source and create a <div>...
<div class="myclass">some content</div>
It then for no apparent reason strips the class from the <div>, so when I hit source again it has been changed to...
<div>some content</div>
I presume this irritating behaviour can be turned off in the config.js, but I have been digging and cant find anything in documentation to turn it off.
Disabling content filtering
The easiest solution is going to the config.js and setting:
config.allowedContent = true;
(Remember to clear browser's cache). Then CKEditor stops filtering the inputted content at all. However, this will totally disable content filtering which is one of the most important CKEditor features.
Configuring content filtering
You can also configure CKEditor's content filter more precisely to allow only these element, classes, styles and attributes which you need. This solution is much better, because CKEditor will still remove a lot of crappy HTML which browsers produce when copying and pasting content, but it will not strip the content you want.
For example, you can extend the default CKEditor's configuration to accept all div classes:
config.extraAllowedContent = 'div(*)';
Or some Bootstrap stuff:
config.extraAllowedContent = 'div(col-md-*,container-fluid,row)';
Or you can allow description lists with optional dir attributes for dt and dd elements:
config.extraAllowedContent = 'dl; dt dd[dir]';
These were just very basic examples. You can write all kind of rules - requiring attributes, classes or styles, matching only special elements, matching all elements. You can also disallow stuff and totally redefine CKEditor's rules.
Read more about:
Content filtering in CKEditor – why do you need content filter.
Advanced Content Filter – in deep description of the filtering mechanism.
Allowed content rules – how to write allowed content rules.
I found a solution.
This turns off the filtering, it's working, but not a good idea...
config.allowedContent = true;
To play with a content string works fine for id, etc, but not for the class and style attributes, because you have () and {} for class and style filtering.
So my bet is for allowing any class in the editor is:
config.extraAllowedContent = '*(*)';
This allows any class and any inline style.
config.extraAllowedContent = '*(*);*{*}';
To allow only class="asdf1" and class="asdf2" for any tag:
config.extraAllowedContent = '*(asdf1,asdf2)';
(so you have to specify the classnames)
To allow only class="asdf" only for p tag:
config.extraAllowedContent = 'p(asdf)';
To allow id attribute for any tag:
config.extraAllowedContent = '*[id]';
etc etc
To allow style tag (<style type="text/css">...</style>):
config.extraAllowedContent = 'style';
To be a bit more complex:
config.extraAllowedContent = 'span;ul;li;table;td;style;*[id];*(*);*{*}';
Hope it's a better solution...
Edit: this answer is for those who use ckeditor module in drupal.
I found a solution which doesn't require modifying ckeditor js file.
this answer is copied from here. all credits should goes to original author.
Go to "Admin >> Configuration >> CKEditor"; under Profiles, choose your profile (e.g. Full).
Edit that profile, and on "Advanced Options >> Custom JavaScript configuration" add config.allowedContent = true;.
Don't forget to flush the cache under "Performance tab."
Since CKEditor v4.1, you can do this in config.js of CKEditor:
CKEDITOR.editorConfig = function( config ) {
config.extraAllowedContent = '*[id](*)'; // remove '[id]', if you don't want IDs for HTML tags
}
You can refer to the official documentation for the detailed syntax of Allowed Content Rules
if you're using ckeditor 4.x you can try
config.allowedContent = true;
if you're using ckeditor 3.x you may be having this issue.
try putting the following line in config.js
config.ignoreEmptyParagraph = false;
This is called ACF(Automatic Content Filter) in ckeditor.It remove all unnessary tag's What we are using in text content.Using this command in your config.js file should be turn off this ACK.
config.allowedContent = true;
Please refer to the official Advanced Content Filter guide and plugin integration tutorial.
You'll find much more than this about this powerful feature. Also see config.extraAllowedContent that seems suitable for your needs.
Following is the complete example for CKEDITOR 4.x :
HTML
<textarea name="post_content" id="post_content" class="form-control"></textarea>
SCRIPT
CKEDITOR.replace('post_content', {
allowedContent:true,
});
The above code will allow all tags in the editor.
For more Detail : CK EDITOR Allowed Content Rules
If you use Drupal AND the module called "WYSIWYG" with the CKEditor library, then the following workaround could be a solution. For me it works like a charm. I use CKEditor 4.4.5 and WYSIWYG 2.2 in Drupal 7.33. I found this workaround here: https://www.drupal.org/node/1956778.
Here it is:
I create a custom module and put the following code in the ".module" file:
<?php
/**
* Implements hook_wysiwyg_editor_settings_alter().
*/
function MYMODULE_wysiwyg_editor_settings_alter(&$settings, $context) {
if ($context['profile']->editor == 'ckeditor') {
$settings['allowedContent'] = TRUE;
}
}
?>
I hope this help other Drupal users.
I found that switching to use full html instead of filtered html (below the editor in the Text Format dropdown box) is what fixed this problem for me. Otherwise the style would disappear.
I would like to add this config.allowedContent = true; needs to be added to the ckeditor.config.js file not the config.js, config.js did nothing for me but adding it to the top area of ckeditor.config.js kept my div classes
Another option if using drupal is simply to add the css style that you want to use. that way it does not strip out the style or class name.
so in my case under the css tab in drupal 7 simply add something like
facebook=span.icon-facebook2
also check that font-styles button is enabled
I face same problem on chrome with ckeditor 4.7.1. Just disable pasteFilter on ckeditor instanceReady.This property disable all filter options of Advance Content Filter(ACF).
CKEDITOR.on('instanceReady', function (ev) {
ev.editor.pasteFilter.disabled = true;
});

Links at the start of content elements

TYPO3 adds these links at the start of almost every element:
<a id="c1427"></a>
where number is, I guess, UID of the element.
How TYPO3 render this link and is it possible to disable it for a specific FCE?
It depends on your TYPO3 Version. In 4.5 it is defined via:
tt_content.stdWrap.innerWrap.cObject.default.10.value = <div id="c{field:uid}"
If you use the TS-Objectbrowser, you should find it somewhere in tt_content.stdWrap.*
Depending on the rendering you are using, you could be able to add an if statement like:
tt_content.stdWrap.innerWrap.cObject.default.10 {
# check the uid of the content element which is rendered
if.isInList.field = uid
# do not render if content element uid is 1,2 or 44
if.value = 1,2,44
}
For sure, it depends on your configuration, so you cannot copy & paste. And i did not test this code! But it should show the way to go:)
I think your problem is in tt_content.stdWrap.prepend that is different for any languages different from default language.
Try to put this typoscript in your template:
tt_content.stdWrap.prepend >
tt_content.stdWrap.wrap = <div class="content-element">|</div>