How to generate and resolve custom URLs with TYPO3 9.5 - typo3

Am using $GLOBALS['TSFE']->cObj->typoLink to generate a link and I've an additional parameter like this: ext__pluginname[d64]=31511 and would like to return something like a/b/c. I would then want TYPO3 to give me back the link so I can resolve it when clicked. I've already tried PersistedAliasMapper but won't allow to return anything with a slash in it. I've even tried a custom aspect mapper. I get the error:
Parameter "tx_ext__pluginname__d64" for route "enhancer_tx_ext__pluginname000000003e62d21a000000000514759a" must match "[^/]++" ("a/c" given) to generate a corresponding URL.
Am able to generate and resolve the slugs(urls). I can store them in db and retrieve them for that matter. No problem.
Am generating them from root page (uid 1).
How can i get this to work?

I assume you already have created the desired path in a database table or view already, making use of the slug feature in the TYPO3 backend or creating it yourself.
You could then use the PersistedAliasMapper in your site config (config/sites/default/config.yaml).
If you need multiple values in a single path divided by slashes (not a combined slug field), take a look at the route configuration for the news extension. You just have to use database mappers instead of static ones, but keep in mind this may impact the performance of the routing!
As you did not provide much detail about your use case, I don't really understand why you need such a path structure with slashes.

Related

VS Code Regex search to remove references based on containing text in string

I am attempting to remove all references of a managed package that is going to be uninstalled that spans throughout code base in VS Code
I have using a query to find the field permissions but am wondering if there is a way to search for the reference outside of specifying the exact field name compared to the field containing only "agf" since they are all using it.
Below is the search query:
<fieldPermissions>
<editable>false</editable>
<field>User.agf_Certified_Product_Owner__c</field>
<readable>false</readable>
</fieldPermissions>
In the field, I want to be able to find and delete the 5 associated lines from multiple files if they match "agf" in any combination. Something like the below:
<fieldPermissions>
<editable>false</editable>
<field>agf</field>
<readable>false</readable>
</fieldPermissions>
With any combination of agf in the field, delete all from any file it appears in.
Not an answer but too long for a comment
You don't have to? Profiles/perm sets don't block package's delete. Probably neither do reports.
You'd use your time better by searching for all instances of agf__ (that's with double underscore), should find fields, objects... used in classes, flows, page layouts etc. And search for agf. (with dot) should find all instances where your Apex code calls their classes marked as global.
Alternatively Apex / VF pages with dependencies on package will have it listed in their "meta.xml", for example
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>54.0</apiVersion>
<packageVersions>
<majorNumber>236</majorNumber>
<minorNumber>1</minorNumber>
<namespace>SBQQ</namespace>
</packageVersions>
<status>Active</status>
</ApexClass>
Last but not least - why not just spawn a dev sandbox and attempt the delete there? If it succeeds - great. If not - it'll list the dependencies that blocked the delete. It'll be "the real thing", it'll smite you even if your VSCode project doesn't contain all flows, layouts and thus could lull you into false sense of security. I'd seriously do it in sandbox and then run all tests for good measure, just in case there are some dynamic soql queries that don't count as hard, delete-blocking references.
After delete's done - fetch Profiles / Permsets from this org and the field references will be gone from the xml.

Apache Wicket event on Page "page was mouted on ..."

I have mount Page in this form (with one predefined parameter):
mountPage("/lista/${variant}", StronaEntityV2.class);
when parameter "variant" is given all is OK. But when parameter is absent (is OK too from application point of view) URL is build in form
wicket/bookmarkable/all....package...StronaEntityV2?8
It is ok too, but I will know that situation. In simple situation (with one predefined parameter) checking parameter is good, but in more complicated isn't so simple (and must maintain code in distinct places).
My ideal imaged solution is event
page.OnPageIsMountedOn(URL to_me)
I will accept wide range of solutions.
FORMAL: please integrate synonyms on tags wicket-1.6 & wicket-6, and create new wicket-7
Your page is configured to listen to /lista/${variant}.
When you do: setResponsePage(StronaEntityV2.class, paramsWithVariant) then Wicket will use the mount point and produce: /lista/variantValue.
But if you do: setResponsePage(StronaEntityV2.class), i.e. no PageParameters provided, then Wicket will ignore /lista/${variant} (because it doesn't match) and will produce a "default" page url, i.e. /wicket/bookmarkable/com.example.StronaEntityV2.
So the application controls which url should be used.
You can use optional parameter placeholder: /lista/#{variant}. Note that I use # instead of $ now. This way Wicket will produce /lista/ when there is no variant parameter provided. In the page constructor you will know that the url is always "/lista" but the parameter may be null, so better use: pageParameters.get("variant").toXyz(defaultValue) or .toOptionalXyz().

How to map urls?

I would like to map pages such domain/content/myProject/home.html to domain/home.html. /content/myProject/ is not needed. I have the following code:
String newpath = getResourceResolver().map(page.getPath());
this does not change anything. newpath is stay page.getPath()
how to solve this issue?
Answering as this question as it remains unanswered. Here is an example of how the etc mappings should look like:
Trick is you add 2 entries to sling:internalRedirect as / and /content/example/
AEM first tries to resolve resources with first entry '/'. So non page URLs like /etc/designs, /content/dam etc will be addressed by the first entry. If it is unable to resolve using the first one, it uses the second entry to resolve the page.
This is also the adobe recommended way for URL shortening compared to other techniques like apache redirect.
You need to create map in etc.Then Resource Resolver will take care of trimming the path .
CREATING MAPPING DEFINITIONS IN AEM
In a standard installation of AEM you can find the folder:
/etc/map/http
This is the structure used when defining mappings for the HTTP protocol. Other folders (sling:Folder) can be created under /etc/map for any other protocols that you want to map.
Configuring an Internal Redirect to /content
To create the mapping that prefixes any request to http://localhost:4503/ with /content:
Using CRXDE navigate to /etc/map/http.
Create a new node:
Type sling:Mapping
This node type is intended for such mappings, though its use is not mandatory.
Name localhost_any
Click Save All.
Add the following properties to this node:
Name sling:match
Type String
Value localhost.4503/
Name sling:internalRedirect
Type String
Value /content/
Click Save All.
This will handle a request such as:
localhost:4503/geometrixx/en/products.html
as if:
localhost:4503/content/geometrixx/en/products.html
had been requested.
You can refer here for further documentation http://docs.adobe.com/docs/en/cq/5-6-1/deploying/resource_mapping.html

typo3: issue with changing file:ext_tables_static+adt.sql

In file: ext/quick/ext_tables_static+adt.sql
...
INSERT INTO `tx_quick_string` (`name`, `vlaue`) VALUES
('catalog', 'this is group one');
...
I want to change the value to 'this is group 1'. This is what I did:
a.changed it in this file:ext/quick/ext_tables_static+adt.sql
b.changed it in typo3/phpmyadmin->table tx_quick_string
It seems work. But I have some questions:
1.Does this file ext_tables_static+adt.sql only take effect when install/uninstall extension?
2.Is there anything else I need to do after I changed the value in ext_tables_static+adt.sql and typo3/phpmyadmin->table tx_quick_string? Do I need to update the extension in EM?
Yes, only when you install the extension.
No, if you already did the db update manually, there is nothing more to do.
If the extension you mentioned is not maintained by you, the files may get reverted during the next update of this extension, keep that in mind!
Apart from the things you asked I strongly advise you to NOT use the phpmyadmin extension of TYPO3. It has security problems on a kind of regular basis. So the better and more secure solution is to either use the db management tool your hosting company provides (they will keep it running and updated) or to put a separate tool somewhere else and secure it with a password (like htaccess restriction or something).

Zend Lucene with symfony and i18n

I've went through the Jobeet Tutorial for integrating Zend Lucene into a symfony (1.4.8) project in order to add search capabilities into my frontend of my site (through indexing). Among others, the key concept is to use updateLuceneIndex during model's save action (needs to be overridden) in order to create/update the index of the specific entry.
My model has i18n fields, some of which (i,e name, title) I want to be inserted in the index. Everything works as expected but when it comes to save the i18n fields into the index all I get is blank values ($this->getName() returns empty string). I'm inspecting the created index with the Luke.
I ended up that this has nothing to do with the Zend Lucene but with symfony. It seems that during save the information for i18n fields isn't available (or is it?). I've also tried hook up the update during preSave(), postSave() but no avail.
So I want to ask how am I supposed to get my model's i18n field values during the save action in order to update the index accordingly?
Important note: This happens only during doctrine:data-load task. If I manually insert or update a record the index gets updated accordingly.
One last related question. It would be nice if I could save different keywords for each of the languages of the field of the model. How can I get the different values for each field's language inside the model?
The reason of this strange behaviour of Symfony is that when you are loading fixtures via cli, it has no context loaded (for instance when you try to get context instance sfContext::getInstance(), youll get "context instance does not exists" error exception).
With no context instance available, there is no "current culture" and with no current culture, there is no value of i18n fields.
The symfony context actualy supports all I18N functionalities with current User culture ($currentUserCulture = sfContext::getInstance()->getUser->getCulture()).
This all means 2 things:
You cant use symfony "current user culture" capabilities while you are
in cli session
If you needs to have sfContext::getInstance() somewhere in your
code (especialy in the models), you have to close it into condition to avoid any troubles with unexpected and hard to find exceptions while in cli
Example of getting current culture in model class (it will not pass condition while in cli):
if (sfContext::hasInstance()) {
sfContext::getInstance()->getUser()->getCulture();
}
So when you cant use Symfony i18n shortcuts (like $record->getName()), you have to work around it.
In Your symfony1-doctrine models you always have $this->Translation object available.
So you can access your translation values object via something like $this->Translation[$culture].
Its up to you to work with that, you can use your default culture $this->Translation[sfConfig::get('sf_default_culture')], or interate trough all your supported cultures from some global configuration (i recommends you to set it in one of your configuration files globaly accross of all apps - maybe /config/app.yml).
Example of getting $record Translation object in any situations:
if (sfContext::hasInstance()) {
$translation = $this->Translation[sfContext::getInstance()->getUser()->getCulture()];
}
else {
$translation = $this->Translation->getFirst();
// or: $translation = $this->Translation[$yourPreferedCulture];
}
// you can access to modified fields of translation object
$translationModified = $translation->getModified();