How can one detect transclusion depth? - mediawiki-templates

In MediaWiki, is there a standard pattern that you can include in a template body to detect depth of transclusion?
Specifically, let's assume
Template:Myinfobox
contains such a pattern that displays "native myinfobox call" for depth 1 transclusion and "transclusion call" otherwise.
Then, if page
Mypage
calls
{{Myinfobox}}
it should display "native myinfobox call" while any page that calls
{{Mypage}}
should display "transclusion call"
Does anyone know such a pattern that does not require the writer of
Mypage
to insert special markup or <noinclude> or <includeonly> tags?

No, there is no such thing. However, you can learn some evil tricks and internals on expansion depth limits and branching at
https://meta.wikimedia.org/wiki/Help:Advanced_templates
https://meta.wikimedia.org/wiki/Help:Expansion_depth
https://meta.wikimedia.org/wiki/Help:Substitution#Multilevel_substitution

Thanks for the pointers. I was aware of these but it's good to have them here. Right now I'm resorting to the following trick (using the terminology of my question): I have a home article parameter in the Myinfobox that the user of the template must set to the name of the page hosting the Myinfobox direct call. Thus Mypage will contain something like:
{{ Myinfobox | … | home article = Mypage | … }}
The Myinfobox template tests whether {{PAGENAME}} equals {{{ home article }}} to determine the message it outputs: "transclusion" in case the 2 values are different, "native" otherwise.
But this is clumsy and places burden on the template user.

Related

Division of a Price in Django Template Syntax

Basically, what I'm trying to do is get a 1/4 of a price in a Django Template Editor.
quote.total is a generated value by the system, for example: 1235.00, and I need to manipulate that value to show 308.75 (1235.00 divided by 4).
I've tried things like using {% widthratio quote.total 4 1 %} to get the quotient, however widthratio rounds the quotient, and I need an exact one.
I've also tried {% widthratio quote.total 4 100 %}, to get the quotient multiplied by 100 (implying that all I'd need to do is figure out how to place a decimal point two places over), but have found no way of using CSS to place a decimal point in.
It is also worth noting that because of the products I am working with quote.total will never have a value in the tenths or hundreths place. I've tried using that to my advantage by adding modulus operators and complex math rules & logic with no success.
The one problem with the system I am using is I have no access to the backend to create custom functions, and because of the way the system parses the template, I cannot use script tags.
EDIT: I see you cannot use tags since you have no access to the back end. You may need a JS-based solution. I'll leave this answer up in case it helps someone.
This is a pretty common use case. Consider using a custom filter, something like:
template.html
{% load quarter %}
{{quote.total|quarter}}
/your_app/templatetags/quarter.py
from django import template
register = template.Library()
#register.filter()
def quarter(value):
return (float(value) * 0.25)
Documentation on custom filters is here in the Django Docs. Also, as with any template tag, be sure to restart your server after adding it, or it will django will not register the tag and will throw an error. This is true of production and development servers.

Refactor Massive Cucumber Step Definition

My team is currently taking our old UI acceptance test scripts and automating them. To do this we are using Jruby, Cucumber and Watir-Webdriver. So far the automation process has been going pretty well. The only problem we have is that our step definitions are starting to get a bit out of hand.
For example, in most of our scenarios is a section like this:
Given I press the SEARCH_BUTTON
Then I should land on the SEARCH_PAGE
and the step definitions look like this:
Given(/I press the (.*)$/) do |buttonName|
if buttonName == 'SEARCH_BUTTON'
eval "$browser.#{$DataHash['home']['searchButton']}.when_present.click"
elsif buttonName == 'LOGIN_BUTTON'
eval "$b.#{$DataHash['loginPage']['loginButton']}.click"
elsif buttonName == 'HOME_BUTTON'
eval "$b.#{$DataHash['mainPage']['HomeButton']}.click"
elsif buttonName == 'ADD_PRODUCT_BUTTON'
#This if else ladder goes on like this for another 300+ lines
...
end
end
The $DataHash variable refers to config.yml, which uses a hash to store all of the different web elements we are using.
config.yml
home:
searchButton: "link(:id => 'searchBtn')"
searchTypeSelectBox: "select_list(:name => 'matchType')"
searchResetButton: "button(:id => 'resetSearch')"
#rest of the elements on the home page...
loginPage:
loginButton: "link(:id => 'login')"
#rest of the elements on the login page...
....
So $browser.$DataHash['home']['searchButton'].when_present.click is equivalent to $browser.link(:id => 'searchBtn').when_present.click
We are using this basic step definition for every button that a user could click, and at this point this one step definition is something like 300+ lines of code. Most of which are single lines like above. Our other step definitions have the same sort of problem. Are there any good ways of refactoring our step definitions to make them less bloated, or at least easier to search through, without making the actual steps any less re-useable?
Initially we thought we could have the same step definition in multiple files based on which page was being tested. So in searchDefinitions.rb there would be a step definition for Given(/I press the (.*)$/) do |buttonName| which only had the different buttons found on the search page. Then in homeDefinitions.rb would be the same step definition but only with code for the home page buttons. Basically breaking up the if-else ladder across multiple files. Of course, Cucumber doesn't allow the same step definition in multiple files so now we're at a bit of a loss.
As you mentioned you can reuse steps see Reuse Cucumber steps. But I personally found it pretty complicated when I tried to do it. So, from my side I suggest you to implement Page Object pattern. The idea is that you describe your pages or even some modules like separate entities which provides you with ability to interact with them. For understanding concept see here. And here you can find some example. Assuming this your step definition would like
Given(/I press the (.*)$/) do |buttonName|
#my_home_page.click_search_button
...
end
end
Where click_search_button method encapsulates your 'ladder' logic to press login button if search button is not present yet.
Hopefully it makes sense for you.
Supposing that the minor differences in the eval lines you show don't matter, extract the hash values that vary into a constant
BUTTON_KEYS = {
'search' => %w(home searchButton),
'login' => %w(loginPage loginButton)
# ...
}
and use it in your step definition:
Given(/I press the (.*) button$/) do |button_name|
keys = BUTTON_KEYS['button_name']
eval "$browser.#{$DataHash['#{keys[0]}']['#{keys[1]}']}.when_present.click"
end
Now you have half as many lines of code and less duplication.
I changed the step regexp to include "button", to remove that duplication from the button names, and the button names to be lowercase, as in normal English. Whether or not you're showing your feature files to non-programmers, Cucumber step names should read like natural language so that you can think about product requirements and not implementation details when you're reading them.
Alternative suggestion, valid if the two levels of keys in the the YAML are not really needed:
You could restructure the YAML like so
search button: "link(:id => 'searchBtn')"
search type select box: "select_list(:name => 'matchType')"
search reset button: "button(:id => 'resetSearch')"
# rest of the elements on the home page...
login button: "link(:id => 'login')"
# rest of the elements on the login page...
# ...
Then you wouldn't need the hash at all, and your step could just be
Given(/I press the (.*)$/) do |element_name|
eval "$browser.#{$DataHash['#{element_name}']}.when_present.click"
end
Or you could convert the YAML entirely into a hash (representing the method as a string and calling it with .send), which would prevent you from making some syntax errors.

TAL Condition in Plone to hide HTML if it's a Document (Page)

I'm trying to modify my /portal_view_customizations/zope.interface.interface-plone.belowcontenttitle.documentbyline template with a tal expression, so that the document's author and the modification date do not show if the current portal type is a Document (Page). I don't mind if it shows for News Items, which are time sensitive, but not the Documents/Pages.
This is my failing Plone TAL expression:
<div class="documentByLine"
id="plone-document-byline"
i18n:domain="plone"
tal:condition="view/show and not:python:here.portal_type == 'Document'">
...
I've also tried:
<div class="documentByLine"
id="plone-document-byline"
i18n:domain="plone"
tal:condition="view/show and not:context/portal_type='Document'">
but still no luck. The tracebacks are pretty cryptic and don't relate to the TAL expression. However, if I get rid of my condition for portal_type, then it works again. Any thoughts are appreciated. A manual would be good, but I've looked at the official ones, and they don't mention this.
TAL's underlying TALES, the expression-engine of which TAL makes use of, doesn't support the mixing of expression-types in one expression. It's syntax allows only one expression-type to be specified (defaults to 'path', if omitted, btw), as no delimiter is provided (like a semicolon for chaining several TAL-statements in one element, e.g.).
But instead of mixing three expression-types you can use one python-expression, try:
python: view.show and context.portal_type()!='Document'
Update:
If you have customized a Plone's default-template via portal_view_customizations ('TTW'), now restricted python-methods cannot be accessed, that' why view/show throws an error.
It returns the allowAnonymousViewAbout-property of the site-properties, you can also check this condition yourself and your expression looks like:
tal:define="name user/getUserName"
tal:condition="python:test(name!='Anonymous User') and context.portal_type()!='Document';
Quick'n'dirty alternative:
Do it with CSS:
body.userrole-anonymous .documentByLine {display:none}
body:not(.template-document_view) .documentByLine {display:block}
This will render the hidden elements, but it's helpful for prototyping and such, or 'quickfixes' (no admin available, etc.).

Is it possible to intermix Modular templating and legacy VBScript CT?

In particular, the case I have in mind is this:
##RenderComponentPresentation(Component, "<vbs-legacy-ct-tcm-uri>")##
The problem I'm having is that in my case VBS code breaks when it tries to access component fields, giving "Error 13 Type mismatch ..".
(So, if I were to give the answer, I'd say: "Partially, of no practical use")
EDIT
The DWT above is from another CT, so effectively it's a rendering of component link, that's why parameterless overload as per Nuno's suggestion won't work unfortunately. BTW, the following lines inside VBS don't break and give correct values:
WriteOut Component.ID
WriteOut Component.Schema.Title
EDIT 2
Dominic was absolutely wright: it's a missing dependencies.
A bit more insight to make this info generally useful:
Suppose, the original CT looked like this ("VBScript [Legacy]" type):
[%
Call RenderComponent(Component)
%]
This CT was meant to be called from a PT, also VBS-based. That PT had a big chunk of "#include" statements in the beginning.
Now the story changes: the same CT is being called from another, DWT-based, CT. Obviously (thanks you all for your invaluable help!), dependencies are now not being included anywhere.
The solution to make original CT working again is to explicitly hand-pick and include all necessary VBS TBBs, so the original CT becomes:
[%
#include "tcm:<uri-of-vbs-tbb>"
Call RenderComponent(Component)
%]
Yes - it's perfectly possible to mix and match legacy and modular templates. Perhaps obviously, you can't mix and match template building blocks between the two techniques.
In VBScript "Error 13 Type mismatch" is sometimes used as a secret code that really means "I don't recognise the name of one of your variables, (including the names of Functions and Subs)" In the VBScript templating engine, variables from the page template could be in scope in your component template; it was very common, for example, to put the #includes in the PT so they could be used by the CT. My guess is that your component template is trying to use such a Function, and not finding it.
I know that you can render a Modular Page Template with VBScript Component Presentations, and also a VbScript page template can render a modular Component Template.
Your error is possibly due to something else? Have you tried just using the regular ##RenderComponentPresentation()## call without specifying which template?
The Page Template can render Compound Templates of different flavors - for example Razor, VBS, or XSLT.
The problem comes from the TBBs included in the Templates. Often the Razor templates will need to call functions that only exist in VBScript. So, the starting point when migrating templates is always to start with the helper functions and utility libraries. Then migrate the most generic PT / CT you have to the new format (Razor, XSLT, DWT, etc). This provides a nice basis to migrate the rest of the Templates as you have time to the new format.

.NET frameworks for formatting e-mail messages?

Are there any open source/free frameworks available that take some of the pain out of building HTML e-mails in C#?
I maintain a number of standalone ASP.NET web forms whose main function is to send an e-mail. Most of these are in plain text format right now, because doing a nice HTML presentation is just too tedious.
I'd also be interested in other approaches to tackling this same problem.
EDIT: To be clear, I'm interested in taking plain text form input (name, address, phone number) and dropping it into an HTML e-mail template. That way the receipient would see a nicely formatted message instead of the primitive text output we're currently giving them.
EDIT 2: As I'm thinking more about this and about the answers the question has generated so far, I'm getting a clearer picture of what I'm looking for. Ideally I'd like a new class that would allow me to go:
HtmlMessage body = new HtmlMessage();
body.Header(imageLink);
body.Title("Some Text That Will Display as a Header");
body.Rows.Add("First Name", FirstName.Text);
The HtmlMessage class builds out a table, drops the images in place and adds new rows for each field that I add. It doesn't seem like it would be that hard to write, so if there's nothing out there, maybe I'll go that route
Andrew Davey created Postal which lets you do templated emails using any of the ASP.NET MVC view engines. Here's a video where he talks about how to use it.
His examples:
public class HomeController : Controller {
public ActionResult Index() {
dynamic email = new Email("Example");
email.To = "webninja#example.com";
email.FunnyLink = DB.GetRandomLolcatLink();
email.Send();
return View();
}
}
And the template using Razor:
To: #ViewBag.To From: lolcats#website.com Subject: Important Message
Hello, You wanted important web links right? Check out this:
#ViewBag.FunnyLink
<3
The C# port of StringTemplate worked well for me. I highly recommend it. The template file can have a number of named tokens like this:
...
<b>
Your information to login is as follows:<br />
Username: $username$<br />
Password: $password$<br />
</b>
...
...and you can load this template and populate it like this:
notificationTemplate.SetAttribute("username", Username);
notificationTemplate.SetAttribute("password", Password);
At the end, you get the ToString() of the template and assign it to the MailMessage.Body property.
I recently implemented what you're describing using MarkDownSharp. It was pretty much painless.
It's the same framework (minus a few tweaks) that StackOverflow uses to take plain-text-formatted posts and make them look like nice HTML.
Another option would be to use something like TinyMCE to give your users a WYWIWYG HTML editor. This would give them more power over the look and feel of their emails, but it might just overcomplicate things.
Bear in mind that there are also some security issues with user-generated HTML. Regardless of which strategy you use, you need to make sure you sanitize the user's input so they can't include scary things like script tags in their input.
Edit
Sorry, I didn't realize you were looking for an email templating solution. The simplest solution I've come up with is to enable text "macros" in user-generated content emails. So, for example, the user could input:
Dear {RecipientFirstName},
Thank you for your interest in {ClientCompanyName}. The position you applied for has the following minimum requirements:
- B.S. or greater in Computer Science or related field
- ...
And then we'd do some simple parsing to break this down to:
Dear {0},
Thank you for your interest in {1}. The position you applied for has the following minimum requirements:
- B.S. or greater in Computer Science or related field
- ...
... and ...
0 = "RecipientFirstName"
1 = "ClientCompanyName"
...
We store these two components in our database, and whenever we're ready to create a new instance from this template, we evaluate the values of the given property names, and use a standard format string call to generate the actual content.
string.Format(s, macroCodes.Select(c => EvaluateMacroCode(c, obj)).ToArray());
Then I use MarkdownSharp, along with some HTML sanitizing methods, to produce a nicely-formatted HTML email message:
Dear John,
Thank you for your interest in Microsoft. The position you applied for has the following minimum requirements:
B.S. or greater in Computer Science or related field
...
I'd be curious to know if there's something better out there, but I haven't found anything yet.

Resources