0

I am using the api function module_load_include to include some markup in a custom module. The markup gets included and I indeed see it on my page but I am getting a side effect that the path to the include file also prints on the page along with my markup. Here is what I have that's working but with the unwanted path being printed out.

function mymodule_page_build(&$page) {

  if (!path_is_admin(current_path())) {
    $page['page_top']['mymodule'] = array(
      '#type' => 'markup',
      '#weight' => 25,
      '#markup' => check_plain(module_load_include('inc', 'mymodule', 'inc/markup')),
    );
  }

}

so the markup from my include file renders as HTML but I also see this on the page as well.

/sites/all/modules/custom/mymodule/inc/markup.inc

Just not sure what I am doing wrong, could not find any examples where this api function is used to include within the #markup context.

2

module_load_include returns the file path not the html. However the reason you are seeing the html is due to module_load_include also doing a require_once. An easy way to fix this would be something like the following

function mymodule_page_build(&$page) {
  module_load_include('inc', 'mymodule', 'inc/markup');

  if (!path_is_admin(current_path())) {
    $page['page_top']['mymodule'] = array(
      '#type' => 'markup',
      '#weight' => 25,
      '#markup' => get_my_html(),
    );
  }
}

So now your #markup is a function call. Just make sure your html is wrapped in the function name you want and then use your function name in the #markup key.

Also, you function that contains the markup will be something like this.

function get_my_html() {
  $output = '';

  $output .= '<div><p>Here is some of my HTML OR ALL of my HTML';

  return $output;
}

Hope this helps!

  • A theme function/template file would be better to get the markup, but this is the right idea – Clive Aug 8 '14 at 14:29
  • I agree with Clive while my suggestion does get it done. Registering a theme function really is the Drupal way to go about it. – FatGuyLaughing Aug 8 '14 at 14:31
  • Yeah, I think I am going to define a theme function with a template, I updated the issue tags as it's not truly FAPI, it's more of a theming task. I am pretty new to doing things like this so excuse my lack of knowledge here. Thanks, I will try a few things out and post back. – Danny Englander Aug 8 '14 at 18:26
  • Well thanks, you put me on the right track. This turned out to be pretty trivial. In the end, I used a theme function to create a template and then used '#markup' => theme('mymodule_theme_widget'), to place the template. – Danny Englander Aug 9 '14 at 13:47
  • 1
    @Danny Even better than that would be to use the render array method for theming: $build['foo'] = array('#theme' => 'mymodule_theme_widget', '#param1' => 'bar', '#param2' => 'baz'); – Clive Aug 9 '14 at 17:40
2

Part of the module_load_include code that's responsible for your issue seems to be:

  if (function_exists('drupal_get_path')) {
    $file = DRUPAL_ROOT . '/' . drupal_get_path('module', $module) . "/$name.$type";
    if (is_file($file)) {
      require_once $file;
      return $file;
    }
  }

This function:

  • Includes file when it is called. If that's a markup file, not PHP code, it gets rendered or causes error (depends on your luck)

  • Return file's path and name - and that's what you put into your #markup

Consider using file_get_contents instead, with drupal_get_path to get proper module directory.

  • I think a theme function would be better than file_get_contents (or any other php method you could use like output buffering), likely to be better for caching. Plus you get the warm fuzzy feeling of being all 'Drupal' about it ;) – Clive Aug 8 '14 at 14:31
  • 1
    @Clive Drupal's default caching is turned off if there is a form on page anyway, and question is tagged form-api, so caching is not really an issue. "Your" way is more clean and "by the book", true. What I wrote here was meant as a fastest way for OP to get something that works - without knowing what he actually needs to achieve I didn't dare to suggest deeper changes in his flow. – Mołot Aug 8 '14 at 14:34
  • Fair point about the caching, I didn't notice the form tags... – Clive Aug 8 '14 at 14:38
  • I got rid of the form tags, sorry to mislead. This seemed "form-like" to me because of #markup but in the end it's really a theme function. – Danny Englander Aug 8 '14 at 18:24
2

module_load_include() is just a wrapper around php's require_once, its purpose is to decipher the path required to include a file.

require_once doesn't return what's in the file, and can't be used to assign file contents to a variable; the directive literally pulls the other PHP file into the current request and executes it there and then.

module_load_include() returns the path that was included, which is why you're seeing that in the markup. The include is still processed, so if your .inc file contains print '<p>markup</p>';, it'll be printed at the top of the page (probably why you're not noticing the difference, as you're assigning to page_top).

To stay within the 'proper' bounds of Drupal, you should declare a theme function for your markup (see hook_theme()), and use that theme function in place of what you've already got for '#markup'. The theme system will let you specify what file the markup function is in, so you won't even need module_load_include() any more.

1

Because module_load_include returns the filename/path if successful.

That said, i highly doubt that's the expected way to use that function.

You should use it to include functions, hooks etc etc, not to print the content of a file.

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.