Stuck on making template for Express List Block - Showing images
Permalink
Hey Folks,
Since the Slack/IRC bridge seems to be broken, I'm going to post here, hopefully I can get some help.
I'm trying to create a template for the Express List Block, initially to override when Images are present. Currently the block just says the name of the file and hyperlinks to the image. What I want instead is to actually show the image instead.
I think I've found the relevant section of the view.php file, however I don't think I'm using the methods correctly here as my testing results in php error pages complaining about a method that doesn't exist (at least, how I'm using it).
Here is what I have so far, starting at line 98 in the original view.php:
I will want to revisit how the if/else's work, as they're not quite how I want right now. But I'm trying to figure out how to roughly get the image to show.
The error being thrown is "Call to undefined method Concrete\Core\Search\Result\ItemColumn::getAttributeType()"
Which makes sense as I dig into the API documentation, however I am not entirely sure how to achieve what I want at this point, as I don't know what I can do with "$key", which seems to be a value I can retrieve from the "ItemColumn" aspect (unsure which proper term to use here). I know other "aspects" seem to have the ability to tell if it's an image, but I'm not sure how to bridge that gap right now.
I also added this to the beginning, but it didn't help, unsure if actually needed at all (line 6):
I've been piecing this together from other sources of info like forum posts, etc, no clear answer just yet. Any help would be appreciated! Thanks!
Since the Slack/IRC bridge seems to be broken, I'm going to post here, hopefully I can get some help.
I'm trying to create a template for the Express List Block, initially to override when Images are present. Currently the block just says the name of the file and hyperlinks to the image. What I want instead is to actually show the image instead.
I think I've found the relevant section of the view.php file, however I don't think I'm using the methods correctly here as my testing results in php error pages complaining about a method that doesn't exist (at least, how I'm using it).
Here is what I have so far, starting at line 98 in the original view.php:
foreach ($result->getItems() as $item) { ?> <tr class="<?=$rowClass?>"> <?php foreach ($item->getColumns() as $column) { if ($column->getAttributeTypeHandle() == 'image_file') { ?> <td><img src="<?=URL::to($detailPage, 'view_express_entity', $item->getEntry()->getId())?>"></td> <?php } elseif ($controller->linkThisColumn($column)) { ?> <td><a href="<?=URL::to($detailPage, 'view_express_entity', $item->getEntry()->getId())?>"><?=$column->getColumnValue($item);?></a></td> <?php } else { ?> <td><?=$column->getColumnValue($item);?></td> <?php } ?> } <?php
Viewing 15 lines of 19 lines. View entire code block.
I will want to revisit how the if/else's work, as they're not quite how I want right now. But I'm trying to figure out how to roughly get the image to show.
The error being thrown is "Call to undefined method Concrete\Core\Search\Result\ItemColumn::getAttributeType()"
Which makes sense as I dig into the API documentation, however I am not entirely sure how to achieve what I want at this point, as I don't know what I can do with "$key", which seems to be a value I can retrieve from the "ItemColumn" aspect (unsure which proper term to use here). I know other "aspects" seem to have the ability to tell if it's an image, but I'm not sure how to bridge that gap right now.
I also added this to the beginning, but it didn't help, unsure if actually needed at all (line 6):
I've been piecing this together from other sources of info like forum posts, etc, no clear answer just yet. Any help would be appreciated! Thanks!
Yuck that paste of code block really came out messy, sorry about that.
the snippet you posted doesn't contain any call to method getAttributeType() so the error might be coming from another place in the code.
Sorry, the code in my repo vs in my test system isn't 100% sync'd just yet as I'm trying to suss this out. The line "101" that is throwing the error is:
So yeah, it is being used (just not accurately represented in the original post), and I'm not sure what I should change about how I'm accomplishing this. Namely, I want to tell if the "column" entry is an image file type or not, then act based on that.
if ($column->getAttributeType() == 'image_file') { ?>
So yeah, it is being used (just not accurately represented in the original post), and I'm not sure what I should change about how I'm accomplishing this. Namely, I want to tell if the "column" entry is an image file type or not, then act based on that.
Not 100% sure but $column->getColumnKey() should give you something of the form ak_handle_of_your_attribute
So remove the ak_ and you'll get the attribute's handle.
From there grab the attribute and from it grab the type's handle
So remove the ak_ and you'll get the attribute's handle.
From there grab the attribute and from it grab the type's handle
I am not sure how to get the handle and the attribute type, those steps are unclear to me. I am new to this.
edit: to clarify, I'm not yet sure how to _derive_ the methods to meet the functions you just described. The API documentation really is not self-indicative.
edit: to clarify, I'm not yet sure how to _derive_ the methods to meet the functions you just described. The API documentation really is not self-indicative.
An alternate approach, use my Omni Gallery addon to list express objects and show the images from their attributes as a slider or gallery. It doesn't do live filtering, but if you just need to display the list of images (and some other attributes such as text), Omni Gallery is an easy way to do it.
https://www.concrete5.org/marketplace/addons/omni-gallery/...
https://www.concrete5.org/marketplace/addons/omni-gallery/...
I need to present the information that the Express List Block shows, this is not the job of an image gallery as other info is desired here too. Namely a lot of the attributes of Express Entries.
As long as the express object has an image to start with, Omni Gallery can show attributes of the express object with the image.
As an extreme example, it can pretend to list the express objects as pages using a page list template, where the page list template thinks it is listing pages, but is actually listing the express object and its attributes.
As an extreme example, it can pretend to list the express objects as pages using a page list template, where the page list template thinks it is listing pages, but is actually listing the express object and its attributes.
It's going to be lists of things that have different images associated with each. I want them all to be displayed at once (until a certain number happens) then it moves into pagification. The gallery addon you propose does not look suitable for that.
Furthermore, I need to better understand how to do templates as there's a lot of other blocks I need to write them for and I need a better understanding to do that.
Furthermore, I need to better understand how to do templates as there's a lot of other blocks I need to write them for and I need a better understanding to do that.
I quite understand that you want to learn about doing such for yourself, and as such, an off-the-shelf or near off-the-shelf solution isn't what you are looking for.
(it can handle pagination)
(it can handle pagination)
To get the attribute type handle do this
The line where you're getting the category should probably be outside the loop that runs through all the columns since it never changes. I let you do that properly.
I hope this helps
$columnKey = $column->getColumnKey(); // ak_some_attribute_handle $attrHandle = substr($columnKey, 3); // remove the ak_ to get the attribute's handle $category = $entity->getAttributeKeyCategory(); // get the attribute category (here it's Express) $attribute = $category->getAttributeKeyByHandle($attrHandle); // get the attribute object now that we have its handle and its category // some columns are not for attributes but for other objects like associations or default fields so make sure you do have an attribute before getting its type if ($attribute && is_object($attribute)) { $attrTypeHandle = $attribute->getAttributeTypeHandle(); // do your stuff with $attrTypeHandle }
The line where you're getting the category should probably be outside the loop that runs through all the columns since it never changes. I let you do that properly.
I hope this helps
After wrestling with curly braces and scopes for a while (doing it wrong, clearly) I was able to get it to not throw errors, However the Express List Block is now detecting the date type as an image type, and replacing the date with an img type link, lol, not what I was anticipating. Unsure what I'm doing wrong here: (lines 97 through 121)
<tr class="<?=$rowClass?>"> <?php foreach ($item->getColumns() as $column) { $columnKey = $column->getColumnKey(); // ak_some_attribute_handle $attrHandle = substr($columnKey, 3); // remove the ak_ to get the attribute's handle $category = $entity->getAttributeKeyCategory(); // get the attribute category (here it's Express) $attribute = $category->getAttributeKeyByHandle($attrHandle); // get the attribute object now that we have its handle and its category // some columns are not for attributes but for other objects like associations or default fields so make sure you do have an attribute before getting its type if ($attribute && is_object($attribute)) { $attrTypeHandle = $attribute->getAttributeTypeHandle(); // do your stuff with $attrTypeHandle if ($attrTypeHandle == 'image_file') { ?> <td><img src="<?=URL::to($detailPage, 'view_express_entity', $item->getEntry()->getId())?>"></td> <?php } elseif ($controller->linkThisColumn($column)) { ?> <td><a href="<?=URL::to($detailPage, 'view_express_entity', $item->getEntry()->getId())?>"><?=$column->getColumnValue($item);?></a></td>
Viewing 15 lines of 25 lines. View entire code block.
remove the code you added to spit out the image, all the code, and instead write
And see what happens
echo $attrHandle . ' ' . $attrTypeHandle . '<br>';
And see what happens
Instead of removing the code, I added your line...
This was the output just above the block it seems:
The "Date Modified" column is where it tries to put an img tag, and then every other column visually appears "blank", suggesting to me the iteration breaks after it encounters something that triggers the img replacement once. Unsure if that's correct or not.
$columnKey = $column->getColumnKey(); // ak_some_attribute_handle $attrHandle = substr($columnKey, 3); // remove the ak_ to get the attribute's handle echo $attrHandle . ' ' . $attrTypeHandle . '<br>'; $category = $entity->getAttributeKeyCategory(); // get the attribute category (here it's Express) $attribute = $category->getAttributeKeyByHandle($attrHandle); // get the attribute object now that we have its handle and its category
This was the output just above the block it seems:
xEntryDateCreated xEntryDateModified game_name game_thumbnail text ociation_111e5cde-26bd-11eb-8d56-2221c0b44dd4 image_file ociation_8da745cb-3fc4-11eb-8d56-2221c0b44dd4 image_file ociation_b950c478-26c3-11eb-8d56-2221c0b44dd4 image_file
The "Date Modified" column is where it tries to put an img tag, and then every other column visually appears "blank", suggesting to me the iteration breaks after it encounters something that triggers the img replacement once. Unsure if that's correct or not.
Where you put it it's not goint to work since we don't have the attribute type handle yet. Put it right after
$attrTypeHandle = $attribute->getAttributeTypeHandle();
This is what I get when I move it as you describe: (not sure why it's only doing 2x iterations here... the block has 7x columns "active")
And specifics of where I put it....
game_name text game_thumbnail image_file
And specifics of where I put it....
<?php foreach ($item->getColumns() as $column) { $columnKey = $column->getColumnKey(); // ak_some_attribute_handle $attrHandle = substr($columnKey, 3); // remove the ak_ to get the attribute's handle $category = $entity->getAttributeKeyCategory(); // get the attribute category (here it's Express) $attribute = $category->getAttributeKeyByHandle($attrHandle); // get the attribute object now that we have its handle and its category // some columns are not for attributes but for other objects like associations or default fields so make sure you do have an attribute before getting its type if ($attribute && is_object($attribute)) { $attrTypeHandle = $attribute->getAttributeTypeHandle(); // do your stuff with $attrTypeHandle // BELOW IS TESTING LINE echo $attrHandle . ' ' . $attrTypeHandle . '<br>'; //TESTING LINE FOR MNAKALAY // ABOVE IS TESTING LINE if ($attrTypeHandle == 'image_file') { ?> <td><img src="<?=URL::to($detailPage, 'view_express_entity', $item->getEntry()->getId())?>"></td> <?php
that's normal. Out of your 7 fields only these 2 are attributes. The first 2 are default values (date created and date modified) and the others are all associations.
Only attributes have an attribute type. You said you needed to know which attribute had an image. That's the second one with the attribute type of image_file.
So what we can say is that at least that aspect of the code works correctly
Now you don't see anything because you are outputting an image <img> but instead of the URL to an image you are using the URL to a page
So correct the line above like this and see if it works
Only attributes have an attribute type. You said you needed to know which attribute had an image. That's the second one with the attribute type of image_file.
So what we can say is that at least that aspect of the code works correctly
Now you don't see anything because you are outputting an image <img> but instead of the URL to an image you are using the URL to a page
<img src="<?=URL::to($detailPage, 'view_express_entity', $item->getEntry()->getId())?>">
So correct the line above like this and see if it works
<img src="<?=$attribute->getPlainTextValue()?>">
That resulted in PHP error
Call to undefined method Concrete\Core\Entity\Attribute\Key\ExpressKey::getPlainTextValue()
Call to undefined method Concrete\Core\Entity\Attribute\Key\ExpressKey::getPlainTextValue()
ok. Try this instead
<img src="<?=$attribute->getController()->getPlainTextValue()?>">
That produces:
for "...concrete/attributes/image_file/controller.php"
line 85
Call to a member function getValue() on null
for "...concrete/attributes/image_file/controller.php"
line 85
$f = $this->getAttributeValue()->getValue();
oh yes... Stupid mistake, sorry. I'll get you the correct one in a bit.
This should work
Make sure you replace the whole foreach loop in your code from opening bracket to closing bracket.
<?php $entry = $item->getEntry(); foreach ($item->getColumns() as $column) { $columnKey = $column->getColumnKey(); // ak_some_attribute_handle $attrHandle = substr($columnKey, 3); // remove the ak_ to get the attribute's handle $category = $entity->getAttributeKeyCategory(); // get the attribute category (here it's Express) $attribute = $category->getAttributeKeyByHandle($attrHandle); // get the attribute object now that we have its handle and its category // some columns are not for attributes but for other objects like associations or default fields so make sure you do have an attribute before getting its type if ($attribute && is_object($attribute)) { $attrTypeHandle = $attribute->getAttributeTypeHandle(); if ($attrTypeHandle == 'image_file') { $fv = $entry->getAttribute($attribute); if (is_object($fv)) { ?> <td><img src="<?=$fv->getURL())?>"></td>
Viewing 15 lines of 20 lines. View entire code block.
Make sure you replace the whole foreach loop in your code from opening bracket to closing bracket.
Thanks for all this work everyone. I know I'm going to need to this for a up coming project.