We have a (mvc) solution based on Helix principles that has a breadcrumb feature. So far, all worked fine and there were no dependencies to any other module. Now we added a new feature (blog) that has a few wildcards. The logic for the wildcards is in the feature as it should. But the breadcrumb for all the url's matching a wildcard is the same - which is logical and understandable but not what we want. The breadcrumb should be able to show the correct data, but only our blog feature knows what that is. Linking from breadcrumb to blog would be the worst idea ever, so that is no option.

So I'm looking for ideas on how to solve this..

One possibility that crossed our minds was to create some sort of WildcardContext in the Foundation. The blog feature could add a processor that stores the necessary data in that context. The breadcrumb could read that data while rendering. Would this be a reasonable way to handle this? Or are there (better) alternatives?

  • Do you use wildcard module?
    – Vlad
    Commented Dec 1, 2016 at 13:59
  • I have been toying with this question myself lately. Interestingly enough, I think the breadcrumb control is the only one I can think of where information for the breadcrumb could possibly be shared between modules. One idea I've been bouncing around, but don't consider an answer yet, because I have't found a path to it, is some kind of message service controller. As my components build, can send a message to this entity. Then I let breadcrumbs render at the very end which reads from this message service. Again, not fully baked. But an interesting question. Commented Dec 1, 2016 at 14:01
  • We are not using the wildcard module. It's pretty simple custom code that is used. Based on the url we define the data and get a title which we want to be used in the breadcrumb.. we just need to way to send it there (that's where we might use a pipeline processor)
    – Gatogordo
    Commented Dec 1, 2016 at 14:15
  • My suggestion to check wildcard module which give you possibility use wildcard for different features just using different configurations. github.com/vhil/helpfulcore-wildcards
    – Vlad
    Commented Dec 1, 2016 at 14:37

2 Answers 2


In my attempt to follow the Helix design principles as closely as possible, the issue of Feature-to-Feature module references has come up quite a bit and still remains a bit fuzzy to me.

According to the Helix Documentation, these types of references appear to be permitted in some cases, but are generally discoraged.

A templates class should never define constants for templates that are not created in the module itself. If a module needs to reference a template or field in another module, it should reference the Templates struct in that module ... The practice of referencing different fields across modules by their shared name – an equivalence to duck typing – is discouraged ... If modules need to share data, consider using design patterns such as providers or pipelines to allow one feature to inject content into another feature.

Foundation Providers/Pipelines

The examples of using providers or piplines are pretty limited. The only real example I could find in Habitat was in Feature.Search, which calls upon SearchServiceRepository from Foundation.Indexing, which in turn determines what fields are included in the serach as well as how to format results based on IndexContentProviderBase implementations within each feature.

This is a rather complex approach that is probably overkill for something as simple as a rendering breadcrumbs for wildcard items or when fields from other Features are required, and this probably explains why Habitat has a //TODO for falling back to Title / DisplayName fields in Feature.Metadata.

Following the Foundation.Indexing example in Habitat, you would register a provider or pipeline, from the feature layer, that returns a piece of formatted text when certain conditions are met. For example, this provider/pipeline could have an IsValid() method that determines that it should be used when the context item is a wildcard item (ex: Context.Item.Name == "*") or when the context item is derived from a Blog template.

Since it would be possible for multiple providers/pipelines to be considered valid, I perfer using pipeliens over providers, because you can control the order of how pipelines are executed more easily, and they lend themselves combining values from multiple features. Lastly, the Foundation module would be responsible for running the pipeline (or determining the correct provider), and it can be called from your Breadcrumb feature.

"Project" Features

The idea here is to move your Breadcrumb rendering and related business logic to the Project layer, thus making it a pseudo-feature that is project specific. In the project layer, it can safely make a reference to any Features it needs (in your case, Feature.Blog). Some may feel that this goes against the definitons of a Project and Feature module, however, for simple logic such as Breadcrumbs, it may be acceptable.

Screw it, just make the reference

At the end of the day, we are talking about a single reference, so you may determine that re-architecting your solution to avoid referencing a single field from another feature may be overkill. Hopefully there will be more examples around this issue and clearer definitions in the future so that these references can be avoided.

  • 3
    Haha, the Screw It method is generally how great design turns into poor implementation. that being said, sometimes we aren't afforded the time to create the right way. Nice answer though. Commented Dec 2, 2016 at 0:46

Regarding the Feature-to-Feature, I found the series of blogs which explained most of the cases of the dependency among modules which are same layer


We can find part 2 and 3 in that blog.

  • 3
    Hi. This is a new question; please raise it as such. This site follows a strict Q and A format, for everyone's benefit.
    – Mark Cassidy
    Commented Aug 29, 2017 at 17:28
  • Thanks. I've just create a new question and modify the answer as well.
    – Kim
    Commented Aug 30, 2017 at 1:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.