Blog

New Design, New Publishing Status September 02, 2010

As many of you have noticed, we launched a redesign of the Vae backstage on Sunday.  Thanks for all the compliments.  We're really excited to get this out the door.  We are continuing to fix a few bugs that remain, and hope to have it all cleared up by the end of the week.  Thanks to everyone who reported bugs.

We also want to mention another cool feature that recently rolled out -- three-level publishing status.  It used to be that you could toggle content between 2 states:  Published (green) and Not Published (red).  Well, we've added an in-between state:  Published (Staging only), represented by a yellow icon.

When content is in this state, it will be visible on http://<;you>.vaesite.com/, but not on your live domains.  It's a great way to test new content on your site without taking it fully live.

Price Drop! August 31, 2010

Hey everyone --

It is with great excitement that I can share some recent news.  We have just reworked the Vae hosting plans to be much more affordable and competitive against other hosting providers.

Check them out now at http://vaeplatform.com/pricing

Here's a summary of the changes we made:

  • There is now an unlimited transaction option for eCommerce within each plan level.  So now, you don't have to worry if your customers will be successful -- we will not charge them extra for their success.  Our cheapest unlimited transaction plan starts at $59.95!
  • The flexibility granted by this option also allowed us to reduce the number of plans we offer.  Rather than offering 6 plans, we now only offer 3 full-featured plans, plus the Solo plan.  Furthermore, now more than ever, we expect 95% of our customers to use the Medium plan (with or without the unlimited transaction option).
  • We have raised the amount of included data transfer (bandwidth) from 10GB on the Medium plan to 100GB.  This is a full 10x increase!  This change alone will prevent most customers who currently pay overage charges from paying them in the future.  The Large and X-Large plans include 250GB and 1TB, respectively.

The new plans are available now.

We converted all existing customers plans to the equivalent new plan at the same price point.  For the overwhelming majority of our customers (98%), this will either result in an overall decrease in their spending or their spending will stay the same.  In the few cases of customers whose costs are higher under the new packages (mainly customers from early 2008), we will grandfather them in under their existing plans.

Thanks again for trusting Vae and I hope that these changes help you launch even more websites in the coming months.  Feel free to contact me with any questions.

Better if/elseif/else support update June 30, 2010

A few days ago, we posted about VaeML's better if/elseif/else support.  I mentioned that this was available to all existing sites.  What I forgot to say is that mixing and matching the old-style (<v:else> tag inside the tag that it applies to) and new-style (<v:else> tag after the tag it applies to) on the same site can cause ambiguity when there are nested tags.  We've had some designers get confused because I mistakenly gave the impression that mixing the styles on the same site would work.  This is not the case.

Here's how we're going to handle this:  for new sites, the new style will be expected by default.  For existing sites, the old style will be expected by default.

For existing sites wishing to use the new style, you will need to explicitly disable the old style by going to the Site tab > Optimization tab and unchecking the checkbox for "Allow <v:else> inside the tag they apply to".  For new sites wishing to use the old style, go in and check that checkbox.

VaeML gets better if/elseif/else support June 25, 2010

VaeML, our awesome content presentation language, now has better support for if-statements.  Before, we did not support the idea of an elseif statement, and we had a weird notion that a <v:else> tag should be nested inside a <v:if> tag rather than coming after it.

We have fixed both of these issues.  Observe:

<v:if path="price>500">
Comes with free overnight shipping!
</v:if>
<v:elseif path="price>250">
Comes with free 2-day shipping!
</v:elseif>
<v:else>
Comes with free ground shipping!
</v:else>

It's the new hotness.  Note that you can still nest <v:else> inside <v:if> if you'd prefer it that way.

By the way, if you use Haml, it makes the above look a lot more elegant:

%v:if(path="price>500")
Comes with free overnight shipping!
%v:elseif(path="price>250")
Comes with free 2-day shipping!
%v:else
Comes with free ground shipping!

Enjoy!

VaeQL brings more power to Vae June 15, 2010

We are proud to announce our latest innovation to the Vae platform: VaeQL.  VaeQL stands for Vae Query Language and it is a new layer in the stack that handles the vae() PHP function and paths provided to VaeML tags via the path="" attribute.

VaeQL adds the ability to perform math operations, comparisons, if statements, variables, and PHP functions directly in your path="" attributes and any other place a path is used in Vae.  There's a lot here, so we'll break it down with some examples.

1.  Beef up your <v:if> statements.

Previously, you could only test for the existence of a field within a <v:if> statement.  You can now perform any kind of test, and you may also group tests together.  Let's start with a simple comparison.  This would test if the price structure is greater than 5:

<v:if path="price>5">

Yep, that's now valid VaeML.  <, <=, and >= also work.  You can also test equality and inequality:

<v:if path="name=='Kevin'">
<v:if path="name!='Kevin'">

You may also use a single equal sign for equality and the <> operator for inequality.  Whatever you prefer.  Now, let's get fancy:

<v:if path="(price+5)</home/featured_price">
This item is more than $5 less than the featured item price!
</v:if>

The math operators +, and - work as expected for add and subtract. Multiplication and division are also supported, though their operators are doubled: ** and //.  This is to prevent confusion, as otherwise, we wouldn't know if artist/123 meant the artist with ID 123, or the value of artist divided by 123. 

What if you wanted to test if the price is an even number?  Do this:

<v:if path="!(price%2)">

The % operator is the modulus operator, which represents the remainder from performing an integer division.  In our example, this will be 0 for even numbers.  We add the not operator (the exclamation mark) to take the reverse of this -- return true when the modulus is 0, and false otherwise.

You can also check for multiple conditions:

<v:if path="featured&&digital">This is a featured digital product</v:if>

&& is the symbol for and, || is the symbol for or.  You can also use the words 'and' and 'or' directly.  This would be the same thing as above:

<v:if path="featured and digital">This is a featured digital 
product</v:if>

2.  Adding conditional statements to other VaeML tags

VaeQL also supports the "inline-if" statement popular in many programming langauges.  It works like this:

<v:text path="featured ? featured_description : description" />

If the path featured evaluates to true (it's a checked checkbox or a text field with text in it, etc.), then we will display the featured_description.  Otherwise, just the regular description.

Combine this with the above, and we can make some pretty awesome statements:

<v:text path="(price>=100 and featured) ? 'SUPER VALUE!' : 'Good Value')" />

Note that you can use request variables within VaeQL as well:

<v:text path="($from == 'wholesale' ? wholesale_description : description)" />

Note that in VaeQL, variables correspond to the request variables sent to the page either via a POST or in the URL.  This corresponds (and is linked into) the $_REQUEST array in PHP.

3.  Built-in support for PHP Functions

Vae paths have always supported some functions such as now() and host().  These were built-in functions, and there were only a few available.  Now VaeQL supports the entire PHP function library, and you can even define your own functions in PHP and use them in VaeML.  All the old functions are there too.

Here are some examples:

<v:text path="substr(description, 10, 10)" />
<v:collection path="items[price<PRICECUTOFF()]">

Functions can take arguments, which can be paths, variables, functions, or a full VaeQL query in its own right.

VaeQL also supports "range queries", which will let you specify a range for values.  Use a colon and a function within a predicate.  This would search for items with prices between $10 and $50:

// in __verb.php:
function PRICERANGE() {
  return array(10, 50);
}<v:collection path="items[price:PRICERANGE()]">

4.  Go crazy!

All of these things can be combined and used in all sorts of ways.  Play with it and figure out what works best for your applications.

VaeQL is immediately available on all Vae sites.  As always, thanks for using Vae!

Uniqueness constraints in vae() and <v:collection> May 21, 2010

Let's say you had a catalog of albums stored in a collection.  Each album was released during a specific year.  If you wanted to display to display all the years where your record label created albums, you'd probably do something like:

<v:collection path="/albums" order="DESC(year)">
 <v:text path="year" />
</v:collection>

But this might actually produce something like this:

2010
2010
2010
2009
2009
2008
2008
(etc.)

Eww, look at all those repeats.  That's not what you wanted.

Now Vae provides a way to select only the first record for each year, so you can display your list as intended.  Simply add unique="year" to the <v:collection> tag.  Or, if you're using our PHP API, just add 'unique' => 'year' to your array of options that you pass into vae().

So something like this:

<v:collection path="/albums" order="DESC(year)" unique="year">
 <v:text path="year" />
</v:collection>

Would produce something like this:

2010
2009
2008
(etc.)

Note -- you can look for unique sets of structures by specifying their names separated by commas.  For example unique="year,month".

This was non-trivial for us to implement, so I hope that you are able to take this and go make something cool with it!

Better Permalinks May 13, 2010

First, a programming note to anyone who subscribes to this blog via RSS, most of our updates have moved to Twitter!  Follow us at http://twitter.com/VaePlatform.

We just made a pretty cool change to the way permalinks work on Vae.  They've always been a confluence of 2 things:  they represent both a context and a particular HTML template.  Well, what if you want to render a different page but within the same context?

For example, let's say you have a collection called Items, permalinking to HTML page called item.html.  A permalink for an item (say, Freefall's Road Trip EP album) might look like http://example.com/item/freefall-road-trip-ep.  This is a very semantic, readable, and SEO-friendly URL.  I like it a lot. 

But what if you had another page that renders the reviews of that album?  Say, reviews.html.  Before, you would need to link to that page explicitly and pass the ID of the item in as a parameter.  The URL (as generated by the <v:a> tag) looked like this: http://example.com/reviews/13423. Definitely less obvious and less SEO-friendly.

We've made this better.  Now, the URL will be generated by appending the new template HTML file name to the end of the permalink.  That review link will now look like http://example.com/item/freefall-road-trip-ep/reviews.  Much better.  Our page rendering engine will know to load the HTML file called reviews and render it within the context of the Road Trip EP

The <v:a> tag has been updated to automatically generate the new-style URLs.  If you're generating URLs manually in PHP, you can just start generating links in the new style.

Enjoy!

Release: New Vae Data API for PHP February 18, 2010

It's been a while since we've had a major feature announcement here at Vae CMS, but this is a big one! We're proud to announce Version 2 of the Vae Data API, which is available and running on all Vae accounts as of today.  The new API is an object-oriented replacement for the current vae() and vae_find() functions in PHP, and is also used by any VaeML tag that accepts a path="" attribute.

The biggest feature of the new release is performance.  The old Vae Data API has long been a major bottleneck for Vae sites, especially on sites with large amounts of data or heavy use of associations.  With the new release, we have addressed both of these issues head-on, and have reduced page rendering times by as much as 90% for some pages.  The upgrade is included in all Vae plans for no additional charge.

Behind the scenes, the new API is powered by a new set of Vae Database servers running our new proprietary database server software, VaeDB.  VaeDB is a ground-up rewrite of Vae's data storage and query engine.  All data  (including associations) is now stored in RAM at all times to enable lightning-fast lookups without having to read from the disk. Additionally, VaeDB analyzes your query history to anticipate future queries and get your data ready before you even ask for it.

The other major feature of the new API is its object-oriented nature.  Since examples are worth 1000 words, here's a quick overview of how the new API works.  Non-coders might want to skip this part.

vae() and vae_find() are now the same function and may be used interchangeably.

They return a VaeContext or VaeQuery object that contains the results of your query.  VaeContext and VaeQuery present mostly the same interface.  Let's start up the example with a familiar looking query that retrieves an Artist by ID:

$artist = vae("artists/13421");

Child structures may be accessed by either the arrow operator or via array notation:

echo $artist->name;
echo $artist['name'];

If your query returned multiple contexts (for example if you asked for a collection), you may iterate over the object just like it was an array:

$artists = vae("artists");
foreach ($artists as $artist) {
  echo $artist->name;
}

You can get the ID, permalink, or type of any context easily, via the arrow operator or array notation:

$artist = vae("artists/13421");
echo $artist->id;           // 13421
echo $artist->permalink;    // artist/freefall
echo $artist->type;         // Collection
echo $artist->name->type;   // TextItem
echo $artist->albums->type; // Collection

You can also get info about the structure represented by the context:

$artist = vae("artists/13421");
echo $artist->structure->id;        // 1269
echo $artist->structure->name;      // Artists
echo $artist->structure->type;      // Collection
echo $artist->structure->permalink; // artist   (URL of page to render by default for permalinks)

You can still get the ID in the foreach block too:

$artists = vae("artists");
foreach ($artists as $id => $artist) {
  echo $artist->name;
}

Run scoped XPath queries via the get() method, which supports any valid VaeQL expression:

$artists = vae("artists");
foreach ($artists as $artist) {
  foreach ($artist->get("albums[type='CD']") as $album) {
    echo $album->name . " is a CD!";
  }
}

All query options that were previously supported are still supported.  We have also added query options for pagination. They get passed in as a parameter, after the query. Supported options include filter, groups, limit, order, paginate, page, and skip:

$artists = vae("artists", array('limit' => 10));
$artists = vae("artists", array('paginate' => 5, 'page' => 2));
$albums = $artists->get("albums", array('order' => 'name'));
$albums = $artists->albums(array('order' => 'name')); // same as above, shortcut syntax

Debugging functions like var_dump() (including serialize(), print_r(), var_export(), etc.) will not work directly on the new objects. However, we've wired up a special method that will allow you to debug your code like many of you have always done.  Just invoke the debug method on the object:

var_dump($artist->debug);

Note:  Internally the debug() method is the same as the data() method, which I'll tell you about in a second.

And for the really geeky, a few more implementation details: The $context variable passed into functions registered with vae_register_hook() will now be a VaeContext object. You may manipulate it in your hook functions just as if you had created it in PHP.  Additionally, you can create a VaeContext object out of your own vanilla PHP arrays by invoking the vae_context() function on that array.

You don't have to do anything at all to enjoy the speed boosts and object-oriented features provided by the new API. 

We've rolled it out onto your sites and you are up and rolling.  You may begin using the Object-Oriented features in your PHP code right away as well.  Over the next few months, we will use statistics gathered from the system to build in further optimizations for speed.

*** IMPORTANT ***

For the most part, this API is backwards-compatible with the old API. There is, however, a few things about the new API that may break your old code, though we checked and don't think they affect any websites currently live.

You may no longer directly iterate over the child structures of a context.  For example, this used to work, but will not work anymore:

foreach (vae("artists") as $artist) {
  foreach ($artist as $structure_name => $value) {
    echo $structure_name . ": " . $value . "\n";
  }
}

This change was necessary in order to combine the vae() and vae_find() functions into a single function.

This would work though:

foreach (vae("artists") as $artist) {
  echo "name:  " . $artist->name  . "\n";
  echo "genre: " . $artist->genre . "\n";
  echo "bio:   " . $artist->bio   . "\n";
}

That is, you want your code to explicitly state the name of the structure you wish to access.

If you need to access context data as an array (like before), just invoke the data() method on the object:

foreach (vae("artists") as $artist) {
  foreach ($artist->data as $structure_name => $value) {
    echo $structure_name . ": " . $value . "\n";
  }
}

Also, you need to be careful using objects in "if" statements, as the object will always return true.  For example, this will not work as expected:

if (vae("artists")) {
  echo "There are artists";
}

You can use the ->count() method to achieve what you want:

if (vae("artists")->count) {
  echo "There are artists";
}

Additionally, you should be careful when casting values to a numeric type.  This will not work as expected:

foreach (vae("artists") as $artist) {
  echo (int)$artist->age;
}

This is because objects may not be directly cast to numeric types.  If you need a numeric value, you'll need to first cast to a string.

foreach (vae("artists") as $artist) {
  echo strftime("%m-%d-%Y", (string)$artist->formed_on);
}

I think that covers most of the breaking changes and gotchas.

Thanks for reading this far.  I hope that this made your day.  I also hope that I explained everything fully and that there are no unforeseen complications or bugs.  If you have any questions or notice any issues, please email support@actionverb.com and we'll get it  ironed out immediately.

I really appreciate your support of Vae Platform, and look forward to bringing you many new toys in the future!

Kevin Bombino
Founder
Vae Platform