Well, I am developing a plugin a and I need to display some stuff from my plugin when TYPO3 page load.
Is there some function how to hook action, like in WordPress when page loads than plugin will execute some controller method? Then this controller will produce some output a HTML, which I would like to dispaly in frontend page. Specially I would like display custom script in the head. So the script should be like this <head>...<script>my content</script>...</head>
Ok, what you probably want to do is to develop a so-called TYPO3 extension - that's what plugins/add-ons are called in TYPO3 (which is the term you will likely find google results for).
To get started fast you can try the TYPO3 extension builder (https://docs.typo3.org/typo3cms/extensions/extension_builder/) - which can generate a skeleton extension for you.
For more information you can also have a look at https://docs.typo3.org/typo3cms/CoreApiReference/latest/ExtensionArchitecture/Index.html which explains the concepts in far more detail.
Additional information is available in https://docs.typo3.org/typo3cms/ExtbaseFluidBook/Index.html
in TYPO3 there is something named plugins, but you should differ to the meaning in other context.
first TYPO3 is a CMS which content is structured in a hierarchical tree of pages. These pages are the basis for navigation. and each page contains individual contentelmenents (CE).
As Susi already told: add ons to TYPO3 are in general 'extensions' which could extend(!) the functinality of TYPO3 in different ways. one way is the definition of (TYPO3-)Plugins. These are special ContentElements which enable to show special information.
While normal CEs have all the information what to show in the record (e.g. Text & Image), plugins can be more flexible.
typical examples are: show a list of records OR one record in detail.
These Plugins can be controlled with typoscript or the plugin-CE could have additional fields to hold information what to display.
For detailed information how a plugin is defined consult the links given by Susi.
And be aware: for security reasons it is not possible to just execute a plain PHP file to echo any output. You need to register your plugin using the API, build your output as string and return the generated HTML as string to the calling function. For beginners the ExtensionBuilder will help you to generate a well formed extension which uses the API to register and output your data.
OK guys, thanks for your answers, but it was not very concrete. I found this solution, is not the best one, but it works! If anybody has better please share.
At first, you have to make a file for the class which will be called from the hook at location /your-plugin-name/Classes/class.tx_contenthook.php. Filename have to have this pattern class.tx_yourname.php Inside we will have a code with one method which will be called by the hook.
class tx_contenthook {
function displayContent(&$params, &$that){
//content of page from param
$content = $params['pObj']->content;
//your content
$inject = '4747474747';
// inject content on
$content = str_replace('</body>', $inject. '</body>', $content);
// save
$params['pObj']->content = $content;
}
}
And next, we have to call it on the hook. So Let's go to /your-plugin-name/ext_localconf.php and add there these two lines, which makes a magic and handles also caching.
// hook is called after caching
$TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'][] = 'EXT:' . $_EXTKEY . '/Classes/class.tx_contenthook.php:&tx_contenthook->displayContent';
// hook is called before caching
$TYPO3_CONF_VARS['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'][] = 'EXT:'. $_EXTKEY .'/Classes/class.tx_contenthook.php:&tx_contenthook->displayContent';
I hope this will help those who struggling with typo3.
Related
I have an application in TYPO3 CMS. It has an extension test_extension that has a controller and an action. This action should return some JSON.
class TestRequestController extends ActionController
{
public function testAction(): void
{
echo json_encode([
'test' => 123
]);
}
}
I want to be able to request this action via Postman. How can I do that? TYPO3 version - 8.7. Thanks in advance!
Creating Links
Usually extbase-extensions are created with the help of the extension extension_builder. This extension creates by default templates and links to open list- and detail-view.
It's possible to add additional actions and to create according links.
Also the usage of the templates is not required and your way to return the result of the action without usage of a template is possible.
The logic of the links is this, I break the parts down in single lines:
tx_extension_plugin[controller]=TestRequest
tx_extension_plugin[action]=test
There are still more parameters commonly used like id or search, but it's also possible to define individual parameters.
In your case the listed parameters seem to be sufficient and the link would look like this now:
www.example.com/?id=123&tx_extension_plugin[controller]=TestRequest&tx_extension_plugin[action]=test
for the extension news this would look like this, this is with your parameter-values which are not available in news. This example shows only how the extension-related part is handled (tx_news_pi1):
www.example.com/?id=123&tx_news_pi1[controller]=TestRequest&tx_news_pi1[action]=test
id is for the page here and not a parameter for your extension, else id had to look like this tx_extension_plugin[id]=123. So all extension related parameters have the form tx_extension_plugin[parameter]=value.
While it's possible to create those links with the API, it's easier to create them with the view helpers for the fluid templates. Note that sometimes an hash is added at the end, like this example: &cHash=1234567890.
The cHash-value you can't create without viewHelper or API, so the knowledge about the parameters and the other values is not enough to create the links.
Calling the link
Most often links are directly called by the browser and visible in the URL-bar. But sometimes and in your case you might call the links by AJAX, so that the json is loaded without being directly shown to the user.
It's also possible to wrap the json in script-tags, so that it's every time loaded when the whole page is called, it's not dynamic then and without AJAX it can't adjust to some user-interaction without loading a whole page again.
AJAX responses can be realized in many ways in TYPO3, the most easy one is to define a special page-type and a special page in the pagetree for it. On this page you add the plugin of your extension to return the json. This "Ajax-page" has to be configured to have the correct header for Json and must not return anything else but the JSON, so all HTML-Output has to be disabled.
I have following Action in one of my controllers:
public function validateMessageAction() {
$sth = new ViewModel($this->params('params'));
$adServerOutput = $this->forward()->dispatch('Adserver/Controller/Index', array('action' => 'index'));
$sth->addChild($adServerOutput, 'adServerOutput');
return $sth;
}
Next I have a following template:
adServerOutput: <?php echo $this->adServerOutput; ?><br><br>
Validate message link clicked<br>
Of course the Adserver/Controller/Index and corresponding template exists as well, can be called and once called - shows correct output (from its template).
Unfortunatelly what I get after going to validateMessage action is only the "Validate message link clicked" text - nothing that is setup in Adserver/Controller/Index->indexAction().
Any idea why that works this way ?
Additional information to that might be that actually the validateMessageAction() is also triggered from different controller via $this->forward()->dispatch(...) - maybe that might be the case ?
EDIT: I have checked that as well - and even if the forward() call is only done once - still the problem persists...
I will really greatly appreciate any hints - sitting on this for 2 days already and have no clue even what to check further :)
EDIT: ADDITIONAL TESTS and information
I have done some additional tests and found here are some additional info:
adServer/Controller/indexAction has a layout.phtml template that specified layout (for test purposes shows string "AdServer Layout")
validateMessageAction has a layout.phtml tenplate that specified layout as well (for test purposes shows string "validateMessage Layout)
Now when I only try to call
$a = $this->forward()->dispatch(...)
even if $a is not assigned or anyhow used (only this association is performed) - the page immediatelly starts using Adserver layout (but still contents are not shown) - ignoring the layout that was specified for validateMessageAction() (of course when I remove that assotiation - the layout for validateMessageAction() is back immediatelly).
As I understood in the documentation forward should not make any action, but rather only result with string containing rendered module.
There can however be one additional information in here - is that I use EdpModuleLayouts - maybe that might be somehow source of the problem ?
(Posted on behalf of the OP).
Problem was caused by EdpModuleLayouts - removing layout for Adserver (which actually should not have a layout) solved the problem.
I need to include a PHP file (containing some database-checks 'n' stuff) into a very bad programmed TYPO3 website. They used TemplaVoilà for templating purposes. This is the definition in the master TypoScript template:
[...]
page = PAGE
page {
[...]
10 = USER
10.userFunc = tx_templavoila_pi1->main_page
[...]
}
[...]
Within the used TemplaVoilà template they mapped the main content div (where I'd like to insert my PHP script) with the attribute „field_content“. Don't know if this helps to answer my question.
I tried nearly everything I know to somehow overwrite/fill the „Main Content Area“ through TypoScript, as it is completly empty () on the page I created for my PHP file.
Is it possible to fill a specific mapped tag with my PHP file through TypoScript?
(TYPO3 Version 4.5.32)
I figured out a solution for my problem: With the hint in the answer by Urs (using _INT) I altered an already included DS object to be extended through additional sub-objects (as the markup allows my code to be placed there with some modifications to the stylesheet):
lib.social.20 = PHP_SCRIPT_INT
lib.social.20.file = fileadmin/path_to_my_file
Now it works like a charm althrough it's a bit hacky...
What about
lib.myscript= USER
lib.myscript {
userFunc =user_myScript->main
}
and in the DS
<TypoScript><![CDATA[
10 < lib.myscript
]]></TypoScript>
I'm no TemplaVoilà expert, I just pulled the second snippet from http://typo3-beispiel.net/index.php?id=10
PS: if its's USER, it will be cached, if it's USER_INT, it will prevent static file caching. So you may be better off running those checks in the background via AJAX?
I´ve a bit of a "strategic" problem with creating a nice mod_rewrite solution for a shop. The shop has different kind of pages:
Products (products.php)
Categories (category.php)
Content (content.php)
So the "default" URI´s look like this:
/products.php?id=2
/category.php?id=4
/content.php?id=5
The final result should be a URI´s that include the name of the page (product name, category name).
/chocholate-icecream -> product.php?id=2
/coffe-and-ice -> category.php?id=4
/imprint -> content.php?id=5
My problem now is, that I´ve different types of content which maps to different .php files. And I´m unable to determine to which .php file to route with mod_rewrite as long as I don´t use a cheat "like **/product/**chocolate-icrecream" so that I know that this URI is made for a product. But me and my customer don´t want that solution.
I´ve already started another try:
ALL requests which don´t match a physical file or folder are routed to a mapper.php file. This file looks in the database - I´ve an index with all products, categories etc. - and gives me the correct file.
The mapper then loads the content via CURL and shows it to the user
Basically I thought this was a nice idea but there are so many problems with session handling, , post data, php based redirects (header: ...) with CURL that I really plan to cancel this way etc. etc.
So my question is:
Has anyone of you an idea or a pattern that helps me creating the "good looking" URI´s without using a complex CURL mapper?
Thanks a lot in advance,
Mike
UPDATE to "Include solution":
A good example for the "include problem":
A request for www.shop.com/cart is "rewritten" to "mapper.php". The "mapper.php" decides to include www.shop.com/shoppingcart.php.
shoppingcart.php uses smarty to display the cart. The view asks the $_SERVER variable, if the actual called file is "shoppingcart.php" to decide if the page should be shown in fullscreen mode or with additional columns.
In the "normal / direct" call $_SERVER['PHP_SELF'] would be "/shopping_cart.php" which will show the fullscreen version. Going over the mapper.php with the include option would give us $_SERVER['PHP_SELF']=='/mapper.php' which will give us the view with columns (what´s wrong).
You could do this simply by pointing them all to one page and then including the proper script based on the slug. For example, rewrite all requests like index.php?slug=chocolate-icrecream.
index.php
$resource = fetch_resource($slug);
if ($resource->slug == 'product')
{
include('products.php');
}
else if ($resource->type == 'category')
{
include('category.php');
}
else
{
include('content.php');
}
I don't understand why you don't want to structure your URLs like /product/chocolate-icrecream. That would be good semantic naming that is fairly consistent across the internet nowadays.
Is it possible to include a typoscript file via php?
Normally I would include typoscript with this:
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/templates/typoscript/setup/1.ts">
But I want to do this just with php and not typoscript. Is that possible?
My Purpose: I want to dynamically load typoscript in my page
This can be achieved by invoking accordant functions at an early stage, e.g. in calling or delegating it in ext_localconf.php. For example, the bookstrap package is loading TypoScript in PHP like this:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig(
'<INCLUDE_TYPOSCRIPT: source="FILE:EXT:' . $_EXTKEY
. '/Configuration/PageTS/Mod/Wizards/newContentElement.txt">'
);
Please consider, that TypoScript is cached before the actual front-end rendering starts. This means, that you should not modify TypoScript if you're plugin class or controller logic has been called already.
May be you need to return a value from the php function and use typoscript conditions for choosing the typoscript file.
You might try the following (if I get you right):
$typoscriptFile .= file_get_contents($someFile);
$parser = t3lib_div::makeInstance('t3lib_TSparser');
$parser->parse($typoscriptFile);
$tsArray = $parser->setup;
I really don't know how well that will play with anything related to global typoscript though.
If you wanted a complete correct parse, you might be able to pull something like this off if you populated a fresh t3lib_TStemplate instance from $GLOBALS['TSFE']->tmpl and than ran the code above. Might work, never tried.