How to theme Panels properly? I am using Page Manager and Panels, providing custom node panels with selection rules by type (e.g. one panel variant for article-, one panel variant for blog-content type). This works smooth so far, styling is also neat. But, how can I get more power over the rendering of elements?

There are multiple ways to render specific elements: adding fields, using token, using a custom view only rendering specific fields, using rendered node entity with view mode. using custom panel content with placeholders etc.

What is the best approach here? It would be great to have the ability to add a custom (something) pane element that can be styled in a *.tpl.php.

My current approach would be using display suite, creating view modes for different parts / panel regions and using theme hook suggestions for adding custom node.tpl.php for each view mode. It would not need to invoke views, which is pretty much a overkill?! rendering, additional queries...) and can use already cached entities.

function mytheme_preprocess_node(&amp;$vars) {
  if ($vars['node']-&gt;type == 'my_content_type' &amp;&amp; $vars['view_mode'] == 'panel_region_left') {
    $vars['theme_hook_suggestions'][] = 'node__my_content_type__panel_region_left';
  }

  if ($vars['node']-&gt;type == 'my_content_type' &amp;&amp; $vars['view_mode'] == 'panel_region_right') {
    $vars['theme_hook_suggestions'][] = 'node__my_content_type__panel_region_right';
  }
}


I am not sure how well this will be cached and how much resources it will consume. Any advice would be grateful.
As the official doc says you can do something like 


  panels-pane_node-title.tpl.php
  
  panels-pane_panel_node_title.tpl.php
  
  panels-pane-node-title.tpl.php
  
  panels-pane-node_title.tpl.php


After some search i have found that the suggestions are not detecting by panels, and i end up in this preprocess function.

function MYTHEME_preprocess_panels_pane(&amp;$vars) {
// get the subtype
$subtype = $vars['pane']-&gt;subtype;

// Add the subtype to the panel theme suggestions list
$vars['theme_hook_suggestions'][] = 'panels_pane__'.$subtype;

return $vars;
}


After a long search in forums i found this too,

&lt;?php
function THEMENAME_preprocess_page(&amp;$vars) {
    global $theme_path;
    if($panel_page = page_manager_get_current_page()){

        $target_menu = 'menu-sixth-form-college';
        $current_path = menu_get_item();

        $target_menu_links = menu_load_links($target_menu);
        foreach($target_menu_links as $links) {
            $link_paths[] = $links['link_path'];
        }
        $preferred_link_paths = $link_paths;
        // if the current link is inside menu_load_link
        if(in_array($current_path['href'], $preferred_link_paths)) {
            $vars['theme_hook_suggestions'][] = 'page__sixthform';
        }
        if($panel_page['name'] == 'page-sixth_form_college') {
            $vars['theme_hook_suggestions'][] = 'page__sixthform';
        }
    }
?&gt;


Theme and Cache.

When it comes to caching, i believe Drupal will handle template caching for you as normal page cache. If your dont think it work you can do something like 

&lt;?php
function my_module_function() {
  $my_data = &amp;drupal_static(__FUNCTION__);
  if (!isset($my_data)) {
    if ($cache = cache_get('my_module_data')) {
      $my_data = $cache-&gt;data;
    }
    else {
      // Do your expensive calculations here, and populate $my_data
      // with the correct stuff..
      cache_set('my_module_data', $my_data, 'cache');
    }
  }
  return $my_data;
}
?&gt;