Three new engine features that make the impossible easier

by michal-frackowiak on 21 Oct 2015 20:45

A while ago we silently pushed a number of new features to the Wikidot engine that allow you to create even more advanced constructs! They were first tested by some of our users (thanks!) and now they are ready be announced. Here they are!

[[div_]], [[span_]] — no extra <p> nor <br/>

A number of users pointed out that [[div]] and [[span]] elements often force additional line breaks and paragraphs when compiled into HTML. This is OK when creating text documents but it's asking for trouble when composing layouts where uncontrolled whitespace can ruin the effect. This is especially true with Bootstrap layouts.

Here is a short illustration of the change:

Before

[[span]]
[[a href="#"]] example link [[/a]]
[[/span]]

compiles to

<p>
  <span>
  <br>
  <a href="#" target="_blank">example link</a>
  <br>
  </span>
</p>

After adding underscores

[[span_]]
[[a_ href="#"]] example link [[/a]]
[[/span]]

compiles to

<span>
  <a href="#" target="_blank">example link</a>
</span>

See the difference? Cleaner output and more control. The carousel like the one you can see above is now much easier to type — the parser should not surprise you with extra newlines nor paragraphs now, provided you put underscores to div and span elements.

Logical and mathematical operators — [[#if, [[#ifexpr, [[#expr

When creating dynamical pages, e.g. using ListPages module it was really hard to perform manipulation on numerical values. Some of our users pointed out they could do some great stuff if we added an extra processing layer on top of the parser. So we added three new simple constructs that work like this:

This code…

[[#expr abs(-100) ]]
[[#expr min(4, 1, -4, 6, -10) ]]
[[#expr max(4, 1, -4, 6, -10) ]]
[[#expr 2*4/12-4+66%2 ]] 
is [[#ifexpr 2*4/12-4+66%2 < -3.5 | less than -3.5 | greater than -3.5 ]]
[[#expr 2*(2-1) ]]
[[#if true | display if true | display if false ]]

compiles to…

100
-10
6
-3.33333333333
is greater than -3.5
2
display if true

Sure these expressions are of little use in static pages but they become really useful when combined with ListPages. You could then dynamically add elements (HTML classes, page elements) based e.g. on data forms attributes! See the example below how it's used to add the "active" class to the first carousel element.

Interested? Read more on our doc pages.

[[head]], [[body]] and [[foot]] in ListPages

[[head]], [[body]] and [[foot]] replace prependLine and appendLine parameters with one huge advantage: they can capture blocks of code instead of just one-line values. Here is how they work:

The new code has the form:

[[module ListPages wrapper="no" separate="no"]]
  [[head]]
    [[ul]]
  [[/head]]

  [[body]]
    [[li class="list-item"]]%%title_linked%%[[/li]]
  [[/body]]

  [[foot]]
    [[/ul]]
  [[/foot]]
[[/module]]

This is equivalent to the previously known form:

[[module ListPages wrapper="no" separate="no" prependLine="[[ul]]" appendLine="[[/ul]]"]]
    [[li class="list-item"]]%%title_linked%%[[/li]]
[[/module]]

Note that prependLine and appendLine are inline parameters and can only contain a single line of code. The newer form, although requires more typing, allows several lines of wiki code in header and footer of ListPages. Both appendLine/prependLine and foot/head will continue to be supported, so if you are fine with one-liners you do not need to change your habits.

For more details see ListPages reference docs.

Let's put it together — a dynamically created carousel

The above changes should allow creating much more advanced constructs, e.g. using the Bootstrap carousel. The example below uses three new features, namely:

  1. [[div_]] to create block elements with clean layout,
  2. #ifexpr expression to add the "active" class to the first pane and #expr to bind nav elements to panes,
  3. ListPages with [[head]] and [[foot]].

We will use DataForms to provide content for carousel panes too.

To manage the carousel we created a simple page at http://forms.wikidot.com/carousel:_template containing the following code:

%%form_data{source}%%
----
[[button edit text="Edit" class="btn btn-primary"]] [[button delete text="Delete" class="btn btn-danger"]]
====
[[form]]
fields:
  source:
    label: Source/Description
    type: wiki
  active:
    label: Active
    type: select
    values:
      yes: yes
      no: no
[[/form]]

One could set the category as private which would allow only admins to modify content of the carousel. This would prevent other users from seeing the pages. Actually they do not need to — their content will only be displayed via the ListPages module.

To make viewing and adding new content easier we created an extra "management page" at http://forms.wikidot.com/carousel:_manage

[[module ListPages category="carousel"]]
%%title_linked%% (active:  %%form_data{active}%%)
[[/module]]
[[module NewPage category="carousel" button="Add"]]

Next we put a few pages to create content to work with.

Finally we created a new page at http://forms.wikidot.com/carousel:_example and pasted the following content:

[[module css]]
#u-carousel .carousel-inner {
    background: #888;
    border-radius: 20px;
}

#u-carousel .item {
    text-align: center;
    height: 200px !important;
}

#u-carousel .carousel-control.left {
    border-radius: 20px 0 0 20px;
}

#u-carousel .carousel-control.right {
    border-radius: 0 20px 20px 0;
}
[[/module]]

[[div_ id="u-carousel" class="carousel slide" data-ride="carousel"]]

[!-- Indicators --]
[[module ListPages category="carousel" wrapper="no" separate="no" _active="yes"]]
  [[head]]
    [[ol_ class="carousel-indicators"]]
  [[/head]]

  [[body]]
    [[li data-target="#u-carousel" data-slide-to="[[#expr %%index%% - 1 ]]" class="[[#ifexpr %%index%% == 1 | active ]]"]]@<&nbsp;>@[[/li]]
  [[/body]]

  [[foot]]
    [[/ol]]
  [[/foot]]
[[/module]]

[!-- Wrapper for slides --]
  [[div_ class="carousel-inner"]]
[[module ListPages category="carousel" wrapper="no" separate="no" _active="yes" order="random" limit="5"]]
    [[div_ class="item [[#ifexpr %%index%% == 1 | active ]]"]]
      [[div_ class="carousel-caption"]]
+ %%title%%
%%form_data{source}%%
      [[/div]]
    [[/div]]
[[/module]]
  [[/div]]

  [!-- Controls --]
  [[a_ class="left carousel-control" href="#u-carousel" role="button" data-slide="prev"]]
    [[span class="glyphicon glyphicon-chevron-left"]]@<&nbsp;>@[[/span]]
  [[/a]]
  [[a_ class="right carousel-control" href="#u-carousel" role="button" data-slide="next"]]
    [[span class="glyphicon glyphicon-chevron-right"]]@<&nbsp;>@[[/span]]
  [[/a]]
[[/div]]

That's it! Try it yourself — just go to http://forms.wikidot.com/carousel:_example to see the carousel in action. You can also add new elements at http://forms.wikidot.com/carousel:_manage. The carousel will display content random from five pages.

Hopefully the new improvements will allow even more advanced layouts and content. Take care!

Image credits: Mikael Miettinen, Barron Fujimoto and Hubert Yu, licenced under CC-2.0.

Comments: 10

Add a New Comment