Array indexing in Confluence / Velocity templates - arrays

Our company has begun using Confluence wiki as a documentation site for our teams, and we are implementing a macro called PocketQuery.
This macro pulls SQL data into the site dynamically (we are pulling information like site contacts).
It uses Velocity Templates to display it's data, however I am having issues when doing simple array indexing.
The code:
#set ( $page = $additionalParams.get('Page') )
#set ( $pages = "" )
#if ( $page != $null && $page != "" )
#set ( $pages = $page.split(";") )
#else
#set ( $pages = [] )
#end
The $additionalParams is a list that has been initialised outside of the template, and contains the parameters being passed into macro, in this case:
Page=Site Name;Server
The code I am trying to setup is pulling the Name;Server value from the $additionalParams list, split the value if it is not empty, and then obtain the first value.
I have tried:
$pages.get(1)
$pages[1]
However no value gets pulled (I have also tried zero as an index - same result).
Foreach-ing through this array and printing each entry does work - meaning there are values in there.
All I want to be able to do is index into the array - Can't seem to dig up anyway of doing this.
Could this be converted to a list so it can use the $pages.get method to index into it?
Extending on that would this allow me to use $pages.contains method?
Confluence is using Velocity 1.6.
EDIT:
The solutions on this page and on this page do not work - I am guessing (Wildly) maybe the correct objects are not in the context for the template to use them?
(Would PocketQuery or Confluence be doing this?)
How would I go about using the 'ListTool' ?

The only way I could get this to work with any kind of elegance is as follows:
#set ( $Page = $additionalParams.get('Page') )
#set ( $Pages = [] )
#if ( $Page != $null && $Page != "" )
#foreach($i in $Page.split(";"))
$Pages.add($i)
#end
#end
This initialises a seperate array, loops through the split values and adds them to the seperate array, which seems to be able to use the methods provided in this question
I could then proceed to use it thus:
$Pages.get(0)//Would return "Site Name"
And also
$Pages.contains("Site Name")//Would return true

m.t.bennet is actually right - I tested and it works!!! I took about a month to find the asnwer and his code sniplet works
#set ( $Page = $additionalParams.get('Page') )
#set ( $Pages = [] )
#if ( $Page != $null && $Page != "" )
#foreach($i in $Page.split(";"))
$Pages.add($i)
#end
#end

Related

ref to a hash -> its member array -> this array's member's value. How to elegantly access and test?

I want to use an expression like
#{ %$hashref{'key_name'}[1]
or
%$hashref{'key_name}->[1]
to get - and then test - the second (index = 1) member of an array (reference) held by my hash as its "key_name" 's value. But, I can not.
This code here is correct (it works), but I would have liked to combine the two lines that I have marked into one single, efficient, perl-elegant line.
foreach my $tag ('doit', 'source', 'dest' ) {
my $exists = exists( $$thisSectionConfig{$tag});
my #tempA = %$thisSectionConfig{$tag} ; #this line
my $non0len = (#tempA[1] =~ /\w+/ ); # and this line
if ( !$exists || !$non0len) {
print STDERR "No complete \"$tag\" ... etc ... \n";
# program exit ...
}
I know you (the general 'you') can elegantly combine these two lines. Could someone tell me how I could do this?
This code it testing a section of a config file that has been read into a $thisSectionConfig reference-to-a-hash by Config::Simple. Each config file key=value pair then is (I looked with datadumper) held as a two-member array: [0] is the key, [1] is the value. The $tag 's are configuration settings that must be present in the config file sections being processed by this code snippet.
Thank you for any help.
You should read about Arrow operator(->). I guess you want something like this:
foreach my $tag ('doit', 'source', 'dest') {
if(exists $thisSectionConfig -> {$tag}){
my $non0len = ($thisSectionConfig -> {$tag} -> [1] =~ /(\w+)/) ;
}
else {
print STDERR "No complete \"$tag\" ... etc ... \n";
# program exit ...
}

PHP How to sort foreach based on XML response?

I like to sort my XML response.
This is my code:
// Make some cURL
// Create a simple XML element
$xml = new SimpleXMLElement($resp, LIBXML_NOWARNING, false);
// Output
foreach ($xml->Departure as $departure){
// DEFINE VARIABLES BASED ON XML RESPONSE
$name = $departure['name'];
$rtDate = $departure['rtDate'];
$rtTime = $departure['rtTime'];
$direction = $departure['direction'];
$trainCategory = $departure['trainCategory'];
// CALCULATE DURATION UNTIL NEXT DEPARTURE
$prognosedTime = new DateTime($rtTime);
$currentTime = new DateTime($time);
$interval = $currentTime->diff($prognosedTime);
// OUTPUT FOR BROWSERS
echo $interval->format('%i') . ' Min: ' . $name . ' > ' . $direction . '",';
echo $trainCategory;
echo "<hr/>";
};
?>
Result:
7 Min: Bus 240 > S Ostbahnhof
Bus
-------------------------------------
8 Min: Tram M10 > S+U Warschauer Str.
MetroTram
-------------------------------------
2 Min: U1 > Uhlandstr.
U-Bahn
-------------------------------------
0 Min: Tram M10 > S+U Hauptbahnhof
MetroTram
Problem:
My result should be sorted by $interval
I read
PHP sorting issue with simpleXML several times but I don't get it. So I wanted a shorter solution (for bloody beginners) and found something nice in Sort Foreach Loop after ID. But then I need arrays. Another solution is very close to that and shows how to define arrays: ASC sort foreach. But here I have no idea how to put all my data into an array as I never know how many rows the response will have. I believe I am very close to a solution but don't get it since 2 days. narf

All in one IE conditional function

Trying to create and "all-in-one" IE conditional function.
Pretty much I'd like to be able to do the following:
If no variable is passed then check for IE in general
Pass it 1 version of IE and check for that
Pass an array of versions and check for either of those versions
I am having trouble with the last part which would check for multiple versions of IE. For instance, if I only wanted to target IE versions 7 and 8.
function is_ie( $versions = '' ) {
if( $versions == '' ) {
if ( isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE' ) !== false)
return true;
}
$versions = ( is_array($versions) ) ? $versions : array($versions);
$operand = '';
foreach( $versions as $version ) {
if ( isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ' . $version . '.' ) !== false) {
$operand = true; break;
}
}
return ($operand) ? true : false;
}
Also, is there any sacrifice on performance with this function? Saying I used it a couple times throughout a site. Wondering if I should set some type of GLOBAL variable and check for that instead?

How to restart numbering on PHPWord with addListItem()?

I'm creating a document that will contain multiple numbered lists on a page and have created two list definitions as this:
${'references_' . $testcase} = array('listType'=>PHPWord_Style_ListItem::TYPE_NUMBER_NESTED);
${'procedure_' . $testcase} = array('listType'=>PHPWord_Style_ListItem::TYPE_NUMBER_NESTED);
They're then being called within loops to add to the lists:
for ($i = 1; $i <= 10; $i++) {
$body->addListItem('List Item ' . $i, 0, null, ${'references_' . $testcase});
}
for ($j = 1; $j <= 10; $j++) {
$body->addListItem('List Item ' . $j, 0, null, ${'procedure_' . $testcase});
}
However, the second list numbering starts at 11 - how can I have this set back to 1?
it's an old thread and all but afaik you need to put your lists in seperate textruns to have the numbering start again
I was trying to solve this myself today and I found a fork of PHPWord called PHPWord2. At the moment the code for numbering restart is only in a work branch. Read more at https://github.com/PHPOffice/PHPWord/issues/10. Examples are included in the work branch.

Compact C Folding in Vim

I'm trying to make a simple Vim script that would create very compact top-level folds for c files. Ideally, if it was run on this code:
static void funca(...)
{
...
}
/* Example comment */
static void funcb(...)
{
...
}
Then it would create folds which would look like this when closed:
+-- x Lines: static void funca(...)----------------------
+-- x Lines: static void funcb(...)----------------------
So basically it would be like foldmethod=syntax with foldlevel=1, except that each fold would start one line further up, and would extend further down to include all following blank lines.
I know how to make one of these folds (assuming foldmethod=manual):
/^{<cr>kVnn?^$<cr>zf
But I'm not sure how to put it into a function. This is my effort:
function Cfold()
set foldmethod=manual " Manual folds
ggzE " Delete all folds
while (/^{<cr>) " Somehow loop through each match
kVnn?^$<cr>zf " This would work fine except for the last function
endwhile
endfunction
map <Leader>f :call Cfold()<cr>
But it isn't valid, I'm not entirely sure how functions work. Also, it won't work for the last function in the file, since it won't find '^{' again. If someone could help me get this working, and somehow add a case for the last function in a file, I would be extremely grateful.
Thanks in advance :)
You can create folds programmatically using the foldexpr and foldtext. Try this, though you may have to tweak CFoldLevel so it doesn't swallow non-function parts of the code:
function! CFoldLevel(lnum)
let line = getline(a:lnum)
if line =~ '^/\*'
return '>1' " A new fold of level 1 starts here.
else
return '1' " This line has a foldlevel of 1.
endif
endfunction
function! CFoldText()
" Look through all of the folded text for the function signature.
let signature = ''
let i = v:foldstart
while signature == '' && i < v:foldend
let line = getline(i)
if line =~ '\w\+(.*)$'
let signature = line
endif
let i = i + 1
endwhile
" Return what the fold should show when folded.
return '+-- ' . (v:foldend - v:foldstart) . ' Lines: ' . signature . ' '
endfunction
function! CFold()
set foldenable
set foldlevel=0
set foldmethod=expr
set foldexpr=CFoldLevel(v:lnum)
set foldtext=CFoldText()
set foldnestmax=1
endfunction
See :help 'foldexpr' for more details.

Resources