3

I'm currently building a site with a comprehensive pattern library (along the lines of Lonely Planet's), which Craft seems very well suited to. Each pattern is a partial template and I include it in a page like so:

{% include '_partials/card' with {
  title: 'Something',
  description: 'A bit of text',
  image: 'http://lorempixel.com/400/200/'
} %}

The above, with dummy data, allows me to create an example for the pattern library, but I can then easily reuse the above partial with real data by changing the string values to, eg. entry.title, entry.description, etc. This seems to work pretty well for everything apart from for assets: entry.image is not a string, so there's a type difference with my placeholder image.

So far I've got around this problem with a bit of logic that sets image to entry.image.first().getUrl() if entry.image exists. But it feels like this should really happen inside the partial: firstly it's messy and non-DRY to do this every time / everywhere I include it; secondly, the partial itself should really be able to be responsible for specifying the image transform (if there is one).

So it seems to me there are two possible solutions, but I can't quite figure out how to achieve either. The two options are:

  • Allow the partial to accept either a string or an asset as its image.
  • Create a mock asset object in my pattern page that will behave more like an asset if I feed it into the partial, so the partial will work unproblematically when I give it an entry.image.

In the former case, I can't figure out a neat way to handle an input that might be a string or an asset field (Twig doesn't seem to have, eg. an is string test). In the latter case I have no idea how you'd go about it or even whether it's possible.

If anyone has any ideas or experience of how you might achieve the above, I'd be really grateful!

2

Two ideas come to mind.

First, it would be a lot easier to check if an image exists if you send in null in the include instead of an url to the placeholder image, and then let the cart template know what to do if there isn't an actual image. Something like this:

{% include '_partials/card' with {
  title: 'Something',
  description: 'A bit of text',
  image: null
} %}

And in _partials/card:

{% if image!=null %}
  <img src="{{ image.getUrl({ width: 400, height: 200 }) }}">
{% else %}
  <img src="http://lorempixel.com/400/200/">
{% endif %}

Second option is to have a dummy image in your Assets library, with a known id, and pass that to the card template. Something like:

{% include '_partials/card' with {
  title: 'Something',
  description: 'A bit of text',
  image: craft.assets({ id: 99 }).first()
} %}

The logic in the card template would be a little bit simpler that way I guess. But maybe you risk that the image is deleted at some point and then everything fails? Depending on the images in your Assets library, maybe you could just pick one at random?

{% include '_partials/card' with {
  title: 'Something',
  description: 'A bit of text',
  image: craft.assets({ order: 'RAND()' }).first()
} %}

Might give some weird results, but.. Depends on your project.

| improve this answer | |
  • Thanks - these are some great ideas. One problem about using image: null to get a placeholder is that entry.image.first() will return null if the image was optional and not set. So if you just check for null, you'd potentially get placeholder images cropping up where they shouldn't! However, the underlying idea of checking image against a specific value (rather than using is) works - I just opted to use a particular string (image: 'placeholder') instead of null, and then check for that. Feels a little hacky, but it works, and it's only the pattern examples that will use it. – Nick F Jul 22 '15 at 10:13
  • Got you. Actually I started by writing that image: '' would be easier to check, before opting to use null, as that seemed to be more "correct". But "correct" isn't always the best solution. ;) Glad you got it sorted out! – André Elvan Jul 22 '15 at 10:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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