Is there any way to do something like that.
I have next wiki text:
{{template_open_tag}}
{{template_some_data}}
{{template_close_tag}}
And there are templates:
{{template_open_tag}}
<my-tag>
{{template_some_data}}
bla-bla-bla...
{{template_close_tag}}
</my-tag>
But tag '<bold>' processed already when first template transluded and wiki render this page like:
bla-bla-bla...
</my-tag>
But I want to see:
**bla-bla-bla...**
In my extension:
$wgHooks['ParserFirstCallInit'][] = 'myTagInit';
function myTagInit( &$parser ) {
$parser->setHook( 'my-tag', 'myTagRender' );
}
function myTagRender( $input, $args, $parser, $frame) {
return "**".$input."**";
}
Thank you.
P.S.
And don't ask me why I need this strange markup and don't want to use something like this:
{{template_tag|{{template_some_data}}}}
And {{template_open_tag}} like:
<my-tag>{{{1}}}</my-tag>
To warn you -- this sort of structure will likely be phased out entirely in future versions of MediaWiki, due to its inconsistent behavior and the difficulties it causes with structures like tags and sections.
The correct and future-proof way to do it is indeed to contain both your start and end in one template and pass the middle in as a parameter, eg {{template_tag|{{template_some_data}}}}
Set $wgUseTidy to true to make MediaWiki remove unclosed tags only after all the templates have been evaluated. Alternatively, you can use wikimarkup - as Adrian said - which does not suffer from this limitation.
Update: AFAIK XML-style extension tags are evaluated before way template including happens, so piecing them together from multiple templates is not possible. (Event <ext>{{{1}}}</ext> does not work pre-1.16, though you can make it work in 1.16 with recursiveTagParse.)
instead of using <bold> use ''' in both your {{template_open_tag}} and {{template_close_tag}} and it should render as bla-bla-bla...
Also, you can't do:
{{template_open_tag}}
{{template_some_data}}
{{template_close_tag}}
You have to do
{{template_open_tag}}{{template_some_data}}{{template_close_tag}}
Related
Can someone help me in Implementing XSSFilter, I need to check for XSS vulnerabilities in AEM code, I found that its method boolean check(ProtectionContext context, String src), checks for any XSS infected code, however what will be its context ? It would be nice if someone can share some example.
xssfilter=resourceResolver.adaptTo(XSSFilter.class);
String validjsonString = xssfilter.filter(jsonString);
LOGGER.debug("validjsonString:::::", validjsonString);
String[] uuidArray = getUUIDArray(validjsonString);
I am assuming that you are using the non-depracted Sling APIs here. In this case the ProtectionContext you are missing is coming from the following enum:
org.apache.sling.xss.ProtectionContext
The enum has two values:
HTML_HTML_CONTENT
Escape HTML for use inside element content (rules #6 and - to some degree - #1), using a policy to remove potentially malicous HTML
PLAIN_HTML_CONTENT
Escape plain text for use inside HTML content (rule #1)
Those rules mentioned in those definitions can be found here:
http://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet
So you could do either:
xssfilter.check(ProtectionContext.HTML_HTML_CONTENT, <your-string>);
xssfilter.check(ProtectionContext.PLAIN_HTML_CONTENT, <your-string>);
See: https://sling.apache.org/apidocs/sling11/org/apache/sling/xss/ProtectionContext.html#HTML_HTML_CONTENT
I am playing with the new Azure API Apps (template in Visual Studio 2013 w/ the new SDK bits from 3/24/15) and I'd like have my Swagger UI group my calls by Version #. In my case, I'm currently versioning by URI (I realize REST purists will tell me not to do this - please don't try to "correct my error" here). For instance, I may have these calls:
http://example.com/api/Contacts <-- "latest"
http://example.com/api/1/Contacts
http://example.com/api/2/Contacts
http://example.com/api/Contacts{id} <-- "latest"
http://example.com/api/1/Contacts/{id}
http://example.com/api/2/Contacts/{id}
Functionally, this works great! (Yes, I know some of you will cringe. Sorry this hurts your feelings.) However, my problem is w/ Swagger UI organization. By default, Swagger UI groups these by the Controller Name (Contacts in this case). I see in the SwaggerConfig.cs file that I can change this:
// Each operation be assigned one or more tags which are then used by consumers for various reasons.
// For example, the swagger-ui groups operations according to the first tag of each operation.
// By default, this will be controller name but you can use the "GroupActionsBy" option to
// override with any value.
//
//c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString());
What I don't understand is how I can tweak this to group all of the "latest" together and then all of v1 together and then all of v2 together, etc.
How can I do this? If it absolutely must require that I add the word "latest" (or equiv) into the path in place of the version number, then I can do that but I'd prefer not have to do that.
I believe what you're looking to do is to uncomment a line a few lines below that one in SwaggerConfig.cs
c.OrderActionGroupsBy(new DescendingAlphabeticComparer());
except you'd change the name of the class to something like ApiVersionComparer() and then implement it as a new class:
public class ApiVersionComparer : IComparer<string>
{
public int Compare(string x, string y)
{
// Write whatever comparer you'd like to here.
// Yours would likely involve parsing the strings and having
// more complex logic than this....
return -(string.Compare(x, y));
}
}
If you've gotten far enough to ask this question, I'm sure I can leave the sort implementation for you. :-)
in one extension file: I run below code:
var_dump($GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_watermark_pi1.']);
the result is :
["hooks."]=> array(4) { ["dagou_post."]=> array(1) { ["view."]=> array(2) { ["state."]=> array(1) { ["template"]=> string(11) "###INPUT###" }...
and I can tell it outputs this file: ext_typoscript_setup.txt inside extension:watermark and also the ts settings from global and local pages.
Question:
I checked file: typo3\sysext\cms\tslib\class.tslib_fe.php, and trying to figure out how does this work: $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_watermark_pi1.'], but only saw var $tmpl='';
from this code: $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_watermark_pi1.'], tmpl should be an object, and setup['plugin.']['tx_watermark_pi1.'] should be the property. So anyone can give me some explanation on how does $GLOBALS['TSFE']->tmpl->setup['plugin.']['tx_watermark_pi1.'] work? thanks.
$GLOBALS['TSFE']->tmpl->setup is the cumulative recursive TS setup of your compete website. It gathers all TS templates, found in rootline from your current selected page, parses it and compiles into array.
Obviously, you will find nothing about tx_watermark_pi1 in class.tslib_fe.php, because tslib_fe knows nothing about it - it just creates FE, and one of the tasks is to create tmpl object, that contains complete setup of all TS, found in rootline.
You can find more info on TS parsing here
The typoscript code you write and also the ts-files delivered with the extensions you have installed are parsed to php and then cached. When the frontend is built up, this very big php array is written to this global object and then read from there by several other classes like extension plugins and so on.
You can find that code in the t3lib/class.t3lib_tsparser*.php classes if you want to take a look (although I don't think that will help you).
I've been working on this for sometime now, and I keep running into a wall. I think I'm close, but I figured someone out here in the land of SO might have some deeper insight if not a better way of doing what I'm trying to do.
Basically lets look at this scenario. I have a logo w/ some text that can be set from a few different places. If we look at the setup here is what it looks like.
Hiearchy:
Homepage [has designPath]
- Child Microsite Page [has designPath]
- Logo Component
Logic Flow (in logo component):
if properties.get("logoText") {
use this
} else if currentStyle.get("logoTextFromStyle") {
use this
} else if parentStyle.get("logoTextFromGlobal") {
use this
} else {
be blank
}
My query is with how to get the "parentStyle" of this page. Looking at the docs here: http://dev.day.com/docs/en/cq/5-5/javadoc/com/day/cq/wcm/api/designer/Style.html
I've been able to come up with the fact that I can get a Style object from the "designer" object made available via defineObjects. This is defined with the other utility objects like "pageManager, resourceUtil, resource, currentPage, etc".
With that being said this doesn't seem to work.
//assuming we have getting homePage earlier and it is a valid cq Page resource
Resource homePageResource.slingRequest.getResourceResolver().getResource(homePage.getPath());
Style homePageStyle = designer.getStyle(homePageResource);
at this point homePageStyle is null. To do some more testing I i tried passing currentPage.getPath() instead of homePage.getPath(). I assumed this would give me the currentPage resource and would in end yield the currentStyle object. This also resulted in a null Style object. From this I think I can safely conclude I'm passing the incorrect resource type.
I attempted to load the the cq:designPath into the resource hoping to get a Designer resourceType but to no avail.
I am curious if anyone has run into this problem before. I apologize if I've gone into too much detail, but I wanted to lay out the "why" to my question as well, just in case there was a better way overall of accomplishing this.
I've figured out how to return the style. Here is the rundown of what I did.
//get your page object
Page targetPage = pageManager.getPage("/path/to/target");
//get the Design object of the target page
Design homePageDesign = designer.getDesign(homePage);
//extract the style from the design using the design path
Style homePageStyle = homePageDesign.getStyle(homePageDesign.getPath());
it's very interesting the definition of "getStyle" is a little different from the designer.getStyle vs a Design.getStyle. designer.getStyle asks for a resource whereas Design.getStyle will take the path to a Design "cell" and return the appropriate Style.
I did some testing and it looks like it does work with inherited Styles/Designs. So if my cq:designPath is set at level 1 and I look up a page on at level 2 they will return the Design/Style at the cq:designPath set at level 1.
I hope this helps someone else down the way.
I tried this approach but was not getting the Styles in the Style object.
When we do this:
Design homePageDesign = designer.getDesign(homePage);
In this Design object we get the path till the project node i.e etc/design/myproject
After this if we try to extract the Style from the design path we do not get it.
However I implemented it in a different way.
In the design object, we also get the complete JSON of designs for(etc/design/myproject).
Get the sling:resourceType of the target page and get the value after last index of "/".
Check if this JSON contains the last value. If it contains, you can get your styles, i.e. image, etc.
If i do a mysql-select within the ts-setup and call the result of this select in, lets say, three extensions placed on the same site, does that still mean, that this certain mysql-select is done exactly once within each call of the site?
If so, it would be smarter to do the mysql-select in the typoscript and give the result to the extensions, so i dont have to do the same mysql-select over and over for each extension again, right?
Or is the text from the typoscript handled another way?
Thanx in advance,
Jayden
If that are exactly the same request, it will hopefully cached by mysql-query-cache. But, you are right, the request will be send three times.
If i understand you right, you think about doing sth. like:
lib.mySqlSelect = CONTENT
lib.mySqlSelect ...
plugin.tx_yourplugin.select.cObject < lib.mySqlSelect
That would result in three SQL Querys too.
But you could use an LOAD_REGISTER:
plugin.tx_yourplugin.select = {register:mySqlSelect}
plugin.tx_yourplugin.select.insertData = 1
page.1 = LOAD_REGISTER
page.1.mySqlSelect = CONTENT
page.1.mySqlSelect ...
Assuming "select" has stdWrap property.
If you are writing a new extension, you could use $GLOBALS['TSFE']->register[$register] = $theValue;