Overlay issue in i18n AEM6.0 - aem

We have some sites such as:
/apps/site1
|----i18n
|---data
|---keys
|---languages
|---translator
/apps/site2
|----i18n
|---data
|---keys
|---languages
|---translator
Now when we hit the site, we can see the call libs/cq/i18n/dict.xx-xx.json. Ideally that call should be either from /apps or /etc. How can I achieve this?
OOTB servlet :
#Component
#Service({Servlet.class})
#Properties({#Property(
name = "service.description",
value = {"ResourceBundle Renderer Servlet"}
), #Property(
name = "sling.servlet.paths",
value = {"/libs/cq/i18n/dict"}
)})
public class ResourceBundleExportServlet extends SlingSafeMethodsServlet {

This is not possible, as of aem 6.3 (and earlier versions) that path was hard-coded pretty much everywhere it was used. to use a custom path you will have to-
Register custom servlet at /apps/cq/i18n/dict.xx-xx.json (or path of your choice) to return i18n values.
Change AEM ootb code that uses the hardcoded path to use your custom path.

Related

TYPO3 extbase: Simple readable GET parameters

GET and POST parameters in custom extbase controllers need to be prefixed with the plugin signature to be injected automatically:
<?php
namespace Vendor\Example\Controller;
class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
public function resultsAction($q = null)
{
//...
}
}
Search term $q is only filled automatically if it is passed as ?tx_example_search[q]=foo.
Is there a way declare that the readable version ?q=foo is also fine, and that this should be injected by extbase as well?
(I know that this breaks when multiple plugins on the same page use that parameter, but that's no problem here.)
(The parameter mapping seems already done when ActionController::processRequest() is called, so it must be done earlier.)
You could use the Extbase Plugin enhancer within the routing configuration.
See here: TYPO3 Advanced routing configuration Docs
TYPO3 would then transform the EXTbase URLs into an readable version.
Example:
without the routeEnhancer: yourdomain.com/?tx_example_search[q]=foo
with the routeEnhancer: yourdomain.com/foo
Tipp: You have to define all GET Params otherwise TYPO3 will show the cHash Param.
You can use the method \TYPO3\CMS\Core\Utility\GeneralUtility::_GP($var) in order to retrieve parameters from global variables GET/POST.
Or also \TYPO3\CMS\Core\Utility\GeneralUtility::_GET($var) or \TYPO3\CMS\Core\Utility\GeneralUtility::_POST($var).
Take care of security, those parameters are not sanitized !
If you really want to add the parameter to the action, you have to create an initializeAction() and set the parameter, something like this I guess :
public function initializeResultsAction() {
$myVar = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('q');
$this->request->setArgument('q', $myVar);
}

TYPO3 - includelibs security

I need to include a PHP script in my TS template :
page {
10 = USER_INT
10.includeLibs = lib_confidential.php
10.userFunc = MyClass->ConfidentialRequest
}
It works perfectly but I would like to locate the lib_confidential.php outside of my website root directory (and make something like 10.includeLibs = ../lib_confidential.php). Is it possible to secure my PHP script and how to ? I thought about creating a symlink but that doesn't give any solution.
As your installation needs an update you will have to change the mechanism for including php-functions for the future.
since TYPO3 8 you need to have a class for your php functions. So the autoloader can identify the class and execute the function you need to place the class inside of an extension or declare the class to the autoloader.
Best practice would be site extension where you configure your installation, there you can havea class with all the functions you need.
examples can be found in the manual.

Fluid standalone view in BE context

Given you are in a BE or CLI context (e.g. sending emails via extbase command controller task), the following worked up to 7 LTS for rendering a fluid standalone view:
$view = $this->objectManager->get(StandaloneView::class);
$view->setTemplatePathAndFilename('/Absolute/Path/To/Template.html');
$view->setFormat('html');
$view->getRequest()->setControllerExtensionName('Myextensionname');
return trim($view->render());
However, in 8 LTS, this throws the following exception:
Tried resolving a template file for controller action "Standard->index" in format ".html", but none of the paths contained the expected template fileā€¦ No paths configured.
As suggested in the wiki page at https://wiki.typo3.org/How_to_use_the_Fluid_Standalone_view_to_render_template_based_emails#Usage_in_TYPO3_8.7, I tried setting layout and partial root paths for the view:
$view->setLayoutRootPaths(['EXT:Myextensionname/Resources/Private/Layouts/']);
$view->setPartialRootPaths(['EXT:Myextensionname/Resources/Private/Partials/']);
However, this won't do the trick.
Digging a bit deeper, I could imagine that one would have to set the controller and action name, e.g. by setting the controller context, but that does not seem to be a solid solution as multiple other class instances are tied to it.
What is the correct way to render fluid standalone views in 8 LTS?
Here an example from our current webproject where we want to show a simple note in backend context based on a FLUID HTML in TYPO3 8.7
protected function renderMarkup(): string
{
$standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
$standaloneView->getRequest()->setControllerExtensionName('in2template');
$templatePathAndFile = 'EXT:in2template/Resources/Private/Templates/Tca/ToolbarNoteEmptyFields.html';
$standaloneView->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFile));
$standaloneView->assign('toolbar', 'toolbarstuff');
return $standaloneView->render();
}
StandaloneView likes to receive all template paths (partial, template and layout root paths) so if you don't already provide all of them, you should do so. The reason being that the naming "Standalone" refers to the view being tied neither to a specific MVC action nor a specific extension context.
That said, if you use 8.7.5 there's a chance you are hit by a regression that is going to be solved by https://review.typo3.org/#/c/53917/ so it might be worth checking that out before you do a major refactoring. Technically the StandaloneView can be operated like a TemplateView with extension context, it's just not officially supported behavior and TYPO3 may not consistently apply all of the context you expect.
In my 8.7 extension I use the following code to get the StandaloneView:
$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
/** #var StandaloneView $emailView */
$emailView = $this->objectManager->get(StandaloneView::class);
$emailView->getRequest()->setControllerExtensionName($controllerExtensionName);
$emailView->getRequest()->setPluginName($pluginName);
$emailView->getRequest()->setControllerName($controllerName);
$emailView->setTemplateRootPaths($extbaseFrameworkConfiguration['view']['templateRootPaths']);
$emailView->setLayoutRootPaths($extbaseFrameworkConfiguration['view']['layoutRootPaths']);
$emailView->setPartialRootPaths($extbaseFrameworkConfiguration['view']['partialRootPaths']);
$emailView->setTemplate('Email/' . ucfirst($templateName));
$emailView->assignMultiple($variables);
$emailBody = $emailView->render();
In my function I gave the $controllerExtensionName, $pluginName and $controllerName as parameter with default values, so that other controllers/plugins can use this function, too.

How to set arrays of string to #EnableJpaRepositories from property files

I have a jpa configuration file with #EnableJpaRepositories annotaion. I set this annotaion value from application.properties file like this :
#EnableJpaRepositories("${jpa.repository.packages}")
public class JPAConfiguration {
....
}
and here is my application.properties file:
jpa.repository.packages=com.epms.model
and it works perfect. but i want to specify multiple packages for #EnableJpaRepositories . so i changed my config file to this :
jpa.repository.packages=com.epms.model,com.ecms.model
and also configuration file to this :
#EnableJpaRepositories("#{'${jpa.repository.packages}'.split(',')}")
public class JPAConfiguration {
}
but it's not working . any idea ? how can i do this in my configuration file?
As #amicoderozer is asking, if your classes share a common base package you only must indicate that root package.
If it's not your case (despite you are loading from a config file or you are declaring them manually) maybe the problem (will help posting any Exception or Runtime trace) is the way the split method is used. It returns an array, and I guess the generated code will be like this:
#EnableJpaRepositories("jpa.repository.packages1","jpa.repository.packages2")
That code doesn't compile.
Never tried Spring EL inside the annotation of a component, but despite this, maybe you should indicate the basePackages this way:
#EnableJpaRepositories(basePackages = "#{'${jpa.repository.packages}'.split(',')}")
If doesn't work, I recomend you first test it by manual array declaration:
#EnableJpaRepositories(basePackages = { "com.epms.model","com.ecms.model" })
Be sure all works as you expect, and then try again reading and parsing from config file.
UPDATE:
After some readings, I've concluded that is not possible do what you want. The SpEL is allowed in many places but for annotations there is only documentation and working examples with #Value annotation.

Eclipse OSGI config: relative paths and/or #config.dir-like substitutions?

In my RCP app, I would like to point a property (osgi.java.profile) to a file, and would prefer using paths relative to my installation and config dir.
Is there a definitive spec on what kind of variables are supported in config.ini?
#config.dir seems to be supported, there are references in the builtin, and it's always mentioned as typical example (e.g this SO answer )
However, looking at docs like Eclipse help/Runtime Options, it mentions a few "symbolic locations" like #user.home; however that seems fairly limited and doesn't include #config.dir.
Have even dug into org.eclipse.osgi sources as well, and found no references to this (I did find LocationManager and its hard coded variable substitutions for #user.dir & co).
Can I refer to arbitrary system properties there in some way?
Is this #config.dir a special case, only handled by P2? UPDATE: this seems to be the case.. looking at Eclipse SDK, About .. Configuration dialog shows #config.dir unresolved, probably taken literally by the Equinox..
Thanks for any hints.
I'm late to the party, but hopefully this will help others in the future.
Starting with Eclipse 3.8/4.2 (June 2012), you can substitute Java properties and environment variables into your config.ini file (Eclipse Bug 241192). The Equinox launcher does not support substitution in the eclipse.ini launcher file. The syntax uses dollar signs ($VARIABLE$) to indicate variable substitution:
osgi.configuration.area=$APPDATA$/MyCompany/MyProgram/configuration
osgi.user.area=$APPDATA$/MyCompany/MyProgram/user
osgi.instance.area=$APPDATA$/MyCompany/MyProgram/instance
I imagine you could use something like this for your purposes:
osgi.java.profile=$osgi.install.area$/path/to/profile.txt
You can use a platform URL (Platform URI scheme) to achieve this, i.e.
osgi.java.profile = platform:/config/java_profile.txt
in config.ini, would point to the file java_profile.txt in the current configuration directory.
You might also use existing system properties in config.ini:
osgi.java.profile = ${osgi.configuration.area}/java_profile.txt
From org.eclipse.core.runtime.adaptor.LocationManager, here are the special tokens:
// Data mode constants for user, configuration and data locations.
private static final String NONE = "#none"; //$NON-NLS-1$
private static final String NO_DEFAULT = "#noDefault"; //$NON-NLS-1$
private static final String USER_HOME = "#user.home"; //$NON-NLS-1$
private static final String USER_DIR = "#user.dir"; //$NON-NLS-1$
Why not use two system property variables?
One is named -Dmy.relativepath=filename, which is processed by your code of relative path of eclipse installation folder(workspace or anywhere), another is called -Dmy.path=absolutepath.
The system property is passed to the jvm, you need some tricky(translate the variable in runtime) in the native launcher(like eclipse.exe) if you wants to use variable in its value.
Look how osgi.java.profile is resolved in org.eclipse.osgi.framework.internal.core.Framework:
// check for the java profile property for a url
String propJavaProfile = FrameworkProperties.getProperty(Constants.OSGI_JAVA_PROFILE);
if (propJavaProfile != null)
try {
// we assume a URL
url = new URL(propJavaProfile);
} catch (MalformedURLException e1) {
// try using a relative path in the system bundle
url = findInSystemBundle(propJavaProfile);
}
That means osgi.java.profile must point either to a fully qualified URL, or to a relative path in system bundle (org.eclipse.osgi). This makes impossible usage of installation directory relative path without patching Eclipse.