projection parameters

Topics: General
Oct 25, 2012 at 2:17 PM

Are there any documentation or examples of using parameters with projection?

Developer
Oct 25, 2012 at 3:35 PM

There is an interesting video that explains how Projection works :

http://docs.orchardproject.net/Documentation/Orchard-TV#Projector

Oct 25, 2012 at 4:18 PM

Thanks.... I just watched the video.

The Request:QueryString sounds interesting however, the idea would be to be able to compare to part of the (auto)route instead of some "?param=value"

Let me try to clarify...

Say I'm a software company selling 8 products... I'll certainly come up with an "autoroute" that will use the product name or id as part of the URL so that I can have a generic approach for all products landing pages: testimonials, what's new, features, ... 

I will also need some projections for "latest testimonials", "newest features", "latest articles". Obviously, I would like my that projections get the "related product" from the URL without having to write a ?param=value.

Does it make sense?

Coordinator
Oct 26, 2012 at 12:55 AM

Another projection video, from the Harvest conference: http://www.youtube.com/watch?v=Ka55wTTXZg8&list=UUIo5Bf9vIjfkzRRFKaT_G6Q&index=1&feature=plcp

I think in that case you could write a custom filter, if you can't make tokens work for you.

Oct 26, 2012 at 9:30 AM

A custom filter kinds of defeat the generic flexibility brought by Autoroute... In the same time I realize that this may not be easy to provide contextual data to widgets.

Is there some possibility to specify some value at the "projection" or the "projection widget" level that could be consumed by the "query"? Like this I could create some generic queries...

Coordinator
Oct 26, 2012 at 7:35 PM

Not sure what you mean about Autoroute and filters. Providing contextual data is what tokens do.

Oct 26, 2012 at 11:01 PM

Not sure either what you do not understand.

Let's say, I want to build JetBrains or Atlassian web site. The web site is all about the software/products they are selling. In most cases, the same approach is used whatever the product (overview, features, what's new, downloads, ...). Therefore, it would not make much sense to have have separate pages for each product. I would rather use something more generic.

For example, thanks to Autoroute flexibility I will be able to come up with the following route for a feature content type:

{Content.Fields.FeatureCollection.RelatedProduct.Content.Slug}/features/{Content.Slug}

"RelatedProduct" is content field picker that makes it possible to associate a feature to a specific product.

Thanks to this approach, my content type will work whatever the software/product.

Now, besides the feature, I will need some widgets (some testimonials, latest kb, random customers, ...) on those same pages. However, those widgets need to be "Software/product" aware so that it will display "testimonials", "kbs" or "customers" for the "current" product ({Content.Fields.FeatureCollection.RelatedProduct.Content.Slug}).

Does it make sense? And any idea on how to solve this in an elegant way with Orchard?

Coordinator
Oct 27, 2012 at 12:03 AM

So you want a widget to be aware of what's being displayed in the Content zone. I would not base that on the current path as that would be very brittle: it would break if the site administrator decides to give another route, or the autoroute pattern changes, etc. It would be a lot more robust to base it on the route, but even that looks fragile to me. Then, one of the parts drivers, or the controller, could inject those "widgets" into the zones itself. This is also not optimal because it makes it more difficult to move those shapes around. The simplest solution would be for one of the drivers, or a filter, or the controller, to store its content item id in HttpContext.Items for the widget to pick up.

Oct 28, 2012 at 6:52 AM

>So you want a widget to be aware of what's being displayed in the Content zone.

Well, that could be... I'm not enough into Orchard to know if this is the right approach or not.

The crux of the matter here is that by having such an "autoroute" definition ({Content.Fields.FeatureCollection.RelatedProduct.Content.Slug}/features/{Content.Slug}), my target URL gets a meaning that goes past the content of the content type for which the autoroute is defined. Other piece of information (widgets) displayed on the target URL should be aware in a way or another that this URL is all about the product ({Content.Fields.FeatureCollection.RelatedProduct.Content.Slug}) Product1 or Product2 or whatever...

The key thing here is that the token is used in the middle of the route definition ... it has a functional intent that is somewhat disconnected from the content...

If this problem can't be solved you will end in having many duplicate "projection" definitions. Take Jetbrains for instance. They have something like 12 products. If they were to display some widgets with random testimonials, latest kb and random customers, they would need to create 36 projections (3 for each product) whereas with a more generic approach 3 would be sufficient if a widget could get to know the current product...

To sum up:

On a functional standpoint, I have several products/software that will be displayed in a similar way...

The product name is necessarily part of the target URL...

In order to have a generic approach, I need to share this information (current product) so that the various pieces (widgets) know how to display information specific to that product... 

That said:

This is not a problem specific to Orchard. From my experience, many CMS are struggling with this problem and need all kind of contortions...

Coordinator
Oct 29, 2012 at 6:52 PM

I'm not disagreeing with the requirement, but just saying that relying on the route is probably not the best way to solve the problem. I've offered a couple of approaches. Do any of them look promising?

Nov 1, 2012 at 2:33 PM

Not completely sure but here is an idea:

By specifying an autoroute like ({Content.Fields.FeatureCollection.RelatedProduct.Content.Slug}/features/{Content.Slug}) you are conveying a strong contextual intent that can vary depending on the token value.

Unfortunately, this intent is lost once we are on the specific URL. We'll get  "some-product/features/my-great-feature" and no way for widgets or whatever to get to know that "some-product" sets the functional context...

What about having some **dictionary** associated with a route. Here is how I would define my autoroute:

{Content.Fields.FeatureCollection.RelatedProduct.Content.Slug:CurrentProduct}/features/{Content.Slug:CurrentFeature}

Now from the following URL:  "some-product/features/my-great-feature", I should be able access the value of CurrentProduct (equals to some-product) and CurentFeature (equals to my-great-feature) - could be through a token. Therefore, I will be able to access this information from a widget/projection/query... and have a more generic approach...

Note that this approach doesn't involve much changes. It is completely optional ... just don't provide any Name like CurrentProduct...

Please note that it would be interesting to provide a solution to fall back to a more general projection/query if the contextual data is not available (for instance, CurrentProduct is null/empty...)

How does it sound on a technical standpoint? Feasible?

Coordinator
Nov 3, 2012 at 6:33 AM

RouteValues could certainly be exposed by tokens. Tokens are fairly easy to build.