Can't Override - Don't Understand Why!

Permalink
I've overridden system files before, so I can't for the life of me figure out why I'm having trouble overriding concrete/elements/block_area_header_view.php. I dragged a copy into the elements folder in the root, but my changes aren't reflected in the rendered page. Anyone have any idea why that might be?

The cache is disabled, but I've cleared it as well as manually deleted all files in the cache directory for good measure.

The only thing that's a little different this time around is that I installed an update (5.4.0.5), so the core files reside in the updates directory. I even tried putting the file to override in the root elements folder of the update installation, but that didn't work either.

Thanks for any help or insight you can provide!

-Steve

Shotster
 
jordanlev replied on at Permalink Reply
jordanlev
I dug around in the code, and it looks like that element file cannot be overridden.

It is being called by the "renderElement()" function in concrete/libraries/block_view.php, which has this code:
include(DIR_FILES_ELEMENTS_CORE . '/' . $element . '.php');


So it is only looking in the concrete core folders, not the top-level elements folder.

For better or worse, I don't think the system is currently designed to allow for modification of the core things like this.

-Jordan
Shotster replied on at Permalink Reply
Shotster
Thanks, Jordan! I just found that myself and was about to post a response to my message. I now see that in area.php the following BlockView function is invoked...

public function renderElement($element, $args = array()) {
         extract($args);
         include(DIR_FILES_ELEMENTS_CORE . '/' . $element . '.php');
      }

That of course BEGS the question, why??? I mean, why isn't the usual Loader:element() function invoked (which checks the other directories)?

If this is the intended behavior, then how are developers supposed to know what they can override and what they can't? Is this all documented somewhere? Are we supposed to dig through the code whenever we want to override a file?

I neither understand the rationale nor how it is we're supposed to know what can be overridden and what can't.

Any insights would be appreciated. Thanks much!

-Steve
Shotster replied on at Permalink Best Answer Reply
Shotster
So here's my solution...

I was able to override libraries/block_view.php, so I changed the renderElement() function definition from...

public function renderElement($element, $args = array()) {
         extract($args);
         include(DIR_FILES_ELEMENTS_CORE . '/' . $element . '.php');
      }

...to...

public function renderElement($element, $args = array()) {
         Loader::element($element, $args);
      }

I was then able to override the files I originally wanted to override - namely, elements/block_area_header_view.php and elements/block_area_footer_view.php.

Everything works, and there seem to be no side effects, so I'm guessing it's just a change the core team hasn't gotten around to.

-Steve
jordanlev replied on at Permalink Reply
jordanlev
This is great, and very clever -- if you can't override the thing you're calling, override the thing that's calling the thing you're calling!

(I also like how this forum lets you mark your own answer as "best" ;)

You should submit this change as a patch to the system:
http://www.concrete5.org/index.php?cID=2352...

Thanks for posting the solution so others will know what to do in the future.

-Jordan
Shotster replied on at Permalink Reply
Shotster
And just to be clear, I'm overriding a number of other files in the elements directory, so I assumed (a reasonable assumption it seems to me) that this file would be no different. Instead, I wound up wasting a lot of time troubleshooting.

The reason I want to override the file block_area_header_view.php is to accomplish some styling that I can't figure out how to do otherwise. I can elaborate if anyone's interested in helping me figure out how to style a layout (grid) cell.

-Steve
jordanlev replied on at Permalink Reply
jordanlev
Yeah, I understand your frustration. I have spent countless hours trying to figure out poorly-documented systems (many worse than Concrete5 believe it or not). The only thing I can say is that over time it makes you a better programmer. Not much consolation in the meantime, though, I know.

Concrete5 is an open source project. While there are core developers that work on it, it's not something they're selling and it's not 100% complete, so unfortunately the answer is "you're supposed to dig through the code whenever you run into unexpected behavior". Or use the forums here -- usually people are happy to help.

And of course, if you wind up doing a lot of digging and putting the pieces together, it would be of great help to the rest of the community to write it up and make it available for others to use in the future.

Best of luck.

-Jordan
Shotster replied on at Permalink Reply
Shotster
I guess I'd been operating under the assumption that any file in one of the mirrored directories could be overridden. That was based on my experience with C5 over the past several months. This issue has proven my assumption wrong and taught me I'll have to be more wary in the future. (I hate it when things don't make sense...) :-/

-Steve
jordanlev replied on at Permalink Reply
jordanlev
Yeah, I've been caught by this as well. Seems like 90% of all files are over-ridable, but there's a random assortment that are not for no logical reason I can tell (probably just leftover from an earlier version of the system and no one got around to updating it because other features were deemed more important).
andrew replied on at Permalink Reply
andrew
You got it! :)

There's really no reason why this even needs to be its own function - it should really be using Loader::element() throughout, but it's leftover legacy code.