Styling menu block's menu links in Drupal 7 - templates

I'm trying to style a block in Drupal 7 and I'm having a very hard time figuring things out!
I've used the menu_block module to get all links from the main menu. It produces a block with links in a ul, which I would like to theme as divs for each menu tree.
The styling itself should be easy, but I'm really struggling with finding the theme hook/template filename that I should use to style it.
I've tried to hook into theme_menu_tree and theme_menu_link, but they theme way too many places, and I can't see what I'm styling. I've tried menu-tree--menu-block--main-menu.tpl.php, but the variables are nothing like what I need.
My thought is that I need to style the $content variable in block.tpl.php, but I can't figure out how to do it for a specific block. Where should I hook in, if I want to style the menu points when the block (block type) is display (in the footer)?

I think the easiest (not necessarily the best) place to do this in hook_block_view_alter()
function MYMODULE_block_view_alter(&$data, $block) {
if ($block->module == 'menu_block') {
// Extract the links from the available data
$links = element_children($data['content']['#content']);
$content = '';
// Loop through the links and build up the required output.
foreach ($links as $link) {
$content .= '<div class="something">' . l($link['#title'], $link['#href']) . '</div>';
}
// Assign the new output to the block content...done :)
$data['content'] = $content;
}
}
The Devel module and it's handy dpm() function are your best friend here...they'll let you examine any PHP variable in a nicely structured format in the standard messages area. If you don't already have it installed I'd advise doing so, it's an absolute must for Drupal development.
Don't forget to clear Drupal's caches once you've implemented that hook or the system won't pick it up.

I had a very similar problem trying to figure out how to name my templates and hooks properly. Googling didn't help (way too much noise), but eventually I tried the Menu Block module documentation on drupal.org and it lead me in the right direction...
Template: menu-block-wrapper--main-menu.tpl.php
<nav role="navigation" id="siteNavigation">
<?php echo render($content); ?>
</nav>
Hooks: THEMENAME_menu_tree__menu_block__MENUNAME() and THEMENAME_menu_link__menu_block__MENUNAME():
function THEME_menu_tree__menu_block__main_menu($vars) {
return '<ul class="my-custom-menu-wrapper">' . $vars['tree'] . '</ul>';
}
function THEME_menu_link__menu_block__main_menu($data) {
$el = $data['element'];
// ... render any classes or other attributes that need to go in this <li>
$attr = drupal_attributes($el['#attributes']);
// ... render the menu link
$link = l($el['#title'], $el['#href'], $el['#localized_options']);
// ... and render any submenus
$sub_menu = drupal_render($el['#below']);
return sprintf("\n<li %s>%s %s</li>", $attr, $link, $sub_menu);
}

With print theme you can put CSS styles to the < ul >
print theme('links', array('links' => menu_navigation_links($your_menu_name), 'attributes' => array('class'=> array('ul_class')) ));

Related

How to create html with link-to property inside custom jquery plugin?

I have a custom jquery plugin that use to create drop down html for a search box.
Inside that, html is created as follows.
$.each(stack, function (i, stackItem) {
var url = _getItemURL(stackItem, lang);
if (stackItem.INS !== undefined) {
html += '<li class="row"> ' + stackItem.DS_HIGHLIGHTED + ' - ' + stackItem.E + '<br>' + stackItem.TICKER_DESC + ' </li>';
} else {
html += '<li class="row"> ' + stackItem.COMPANY_DESC_HIGHLIGHTED + '<br>' /*+ _getCountry(stackItem.CC, lang)*/ + ' </li>';
}
itemCount++;
});
As you can see href attribute is used to create links in this html. But when user click on those links application reloads the browser page. I want it to correctly map to different route in the application like in hbs files as follows
<li> {{#link-to 'stock-overview' 'en' 'tdwl' '1010'}}Stock{{/link-to}} </li>
How can I generate html like that inside previous java script code.
Appreciate any help?
First, I would recommend you to think if you really need that jQuery plugin or could go with a plain ember solution. There are some pretty fancy addons like ember-power-select.
But if you really want to do that you need to understand that a {{#link-to}} does not only generate a <a> tag but only handles clicks on it and then doing a transitionTo.
So no, its not possible to do this when you simply append the HTML to the DOM. You would have to catch the click events on the <a> tags manually and then trigger the transition. It depends a bit how you inject the html into the DOM.
One thing you could do is to create a unique id for each <a> tag and after you inserted the html into the DOM you find the <a> tags by the id and attach the onclick event.
A better way would be to create DOM instead of HTML, so manually call document.createElement and then attach the click event.
To trigger the transition you can do something like this inside any Object that has the owner injected (like a component):
Ember.getOwner(this).lookup('controller:application').transitionToRoute('stock-overview', 'en', 'tdwl', '1010');
However cleanly the best solution would be to go for a ember handlebars template and a {{#each}} loop instead of the jQuery solution. To tell you how to do that however we need more information. So best is probably you ask a new question and explain exactly what you want to achieve, and now ask about a problem you have with a probably wrong solution for another problem.

magento product list.phtml

If I click on a product from my product overview on the left side, the shop does not load with the list.phtml. As soon as I swap view to grid or list, it swaps to the list.phtml file and everything is fine. But as I said, if I click on the products on the sidebar, it doesnt work (it's not even affected by list.phtml at all). I removed all the code inside it and it still showed (a bit different, that's why I want to change it) the products, but as soon as I swapped mode, everything disappeared -- as it should. Do you know where I can change that?
Thank you.
It should use list.phtml file. In that file it is defined for both list mode and grid mode.
<?php echo $this->getToolbarHtml() ?>
<?php // List mode ?>
<?php if($this->getMode()!='grid'): ?>
<?php $_iterator = 0; ?>
And
<?php else: ?>
<?php // Grid Mode ?>
<?php $_collectionSize = $_productCollection->count() ?>
You can see something like above code in your list.phtml file,one is for list mode and another for grid mode. This is the default case unless you haven't changed the layout or template code.
If you want to know the file location than you can always enable template path hint. If you don't know how to do that you can follow this.
After knowing from which file it is rendering you can fix it.
Hope this will help.

Print button in Windows 8 Store app HTML + JS for Split Template app

I have an app made in WinJS for Windows 8 App store, and I use the Split Page template. So on the split page I have two colums the one named List column and the one named Item detail column. It is for recipes, and in the list are the pictures and small details, and in the right in the item detail block is the recipe with details and pictures. I want a Print button that will print only the right column with details, not the entire windows with list and etc.
Can someone give me an example better than the one from msdn?
As taken from codeshow.codeplex.com to print a fragment:
function printFrag(printEvent) {
var printTask = printEvent.request.createPrintTask("codeSHOW Print Frag", function (args) {
var frag = document.createDocumentFragment();
frag.appendChild(q(".print #printFromApp").cloneNode(true));
args.setSource(MSApp.getHtmlPrintDocumentSource(frag));
// Register the handler for print task completion event
printTask.oncompleted = printTaskCompleted;
});
}
Which is in turn cloning this html node and then printing it
<div id="printFromApp">
<h2>Invoke print</h2>
<p>Wow, printing is fun.</p>
<button id="invokePrint">Print</button>
</div>
All the print samples can be mostly cut and pasted from there, check it out. It's also available in the Windows Store and is an essential HTML/JS dev tool for Windows Store apps.

Sugarcrm : How to rewrite a document URL

My version :
SugarCRM CE 6.5.2 running on linux
What I want to do :
I've customized the Documents module in "custom/modules/Documents" by writing several logic hooks.
These logic hooks creates new folders in "ressources/" which is my new upload folder. (I've change the 'upload_dir' from "./upload" into "./ressources" in the config.php)
This is done through a custom field created in studio named "folder_name"
And then, the logic hooks cut and paste the document uploaded into this new folder.
What is my problem
So, with all of this, my download url in Edit, Detail and Revisions Subpanel Views is false. I would like to change it to the right folder, like, for example adding a folder parameter in the url
like this :
/index.php?entryPoint=download&folder=Images&id=idDoc&type=Documents
I tried to change the a href link in EditView.tpl or DetailView.tpl, (like )
but it didn't work since they were located in my cache/modules/Documents folder and were overriding when i did a quick repair.
So I copies/pasted the DetailView.tpl and the EditView.tpl into custom/modules/Documents/tpls and tried to override the view.edit.php and the view.detail.php to link the customized templates, but it did not work.
code :
<?php
require_once('include/MVC/View/views/view.detail.php');
class DocumentsViewDetail extends ViewDetail {
function DocumentsViewDetail() {
parent::ViewDetail();
}
function display() {
parent::display();
}
function detailViewProcess() {
$this->processSearchForm();
$this->lv->searchColumns = $this->searchForm->searchColumns;
if (!$this->headers)
return;
if (empty($_REQUEST['search_form_only']) || $_REQUEST['search_form_only'] == false) {
//here we are overriding with your custom template
$this->lv->setup($this->seed, 'custom/modules/Documents/tpls/DetailView.tpl', $this->where, $this->params);
echo $this->lv->display();
}
}
}
?>
Do you have any idea why this doesn't work?
Do you have any idea on how i could rewrite my URLS or override the Edit, Revisions SubPanel and Details Views?
Please answer, this is URGENT
Thank you by advance.
Try adding the folder parameter to the variable $file_url inside the method fill_in_additional_detail_fields() in modules/Documents/Document.php.
[Edited]
EditView: include/SugarFields/Fields/File/EditView.tpl
DetailView: include/SugarFields/Fields/File/DetailView.tpl
<a href="index.php?entryPoint=download&id={$fields.{{$vardef.fileId}}.value}&type={{$vardef.linkModule}}&folder=test" ...
ListView: include/SugarFields/Fields/File/ListView.tpl
<a href="index.php?entryPoint=download&id={$parentFieldArray.ID}&type={$displayParams.module}{$vardef.displayParams.module}&folder=test" ...
So, thanks to #air4x, i did answer my trouble : overriding the DetailView.tpl
To make it upgrade-safe, i copies it from
include/SugarFields/Fields/File/DetailView.tpl
to
custom/include/SugarFields/Fields/File/DetailView.tpl
It works!
BUT there is a big trouble coming...
explanations :
1] I create a new Document, uploading image01 to Folder01. Save. Database ok. in DetailView the folder name is "Folder01" and the link '//Folder01/image01_id' works.
2] I create another new Document, uploading image02 to Folder02. Save. Databse ok. BUT in DetailView the folder's name is not "Folder02" but "Folder01". AND the link is //Folder01/image02_id so it doesn't work, because in database or in my folders, the file is still in Folder02.
Here is my custom/include/SugarFields/Fields/File/DetailView.tpl code :
//BEGIN the code i modified
<span class="sugar_field" id="{{if empty($displayParams.idName)}}{{sugarvar key='name'}}{{else}}{{$displayParams.idName}}{{/if}}">
<a href="ressources/{$fields.folder_name_c.value}/{$fields.{{$vardef.fileId}}.value}" class="tabDetailViewDFLink" target='_blank'>{{sugarvar key='value'}}</a>
</span>
//END the code i modified
{{if isset($vardef) && isset($vardef.allowEapm) && $vardef.allowEapm}}
{if isset($fields.{{$vardef.docType}}) && !empty($fields.{{$vardef.docType}}.value) && $fields.{{$vardef.docType}}.value != 'SugarCRM' && !empty($fields.{{$vardef.docUrl}}.value) }
{capture name=imageNameCapture assign=imageName}
{$fields.{{$vardef.docType}}.value}_image_inline.png
{/capture}
{sugar_getimage name=$imageName alt=$imageName other_attributes='border="0" '}
{/if}
{{/if}}
{{if !empty($displayParams.enableConnectors)}}
{{sugarvar_connector view='DetailView'}}
{{/if}}
I really don't know why my $fields.folder_name_c.value stay from the first document and replace the one in the second document...
Do you know how i could do a sql query in my EditView.tpl to change it and have the right value?
Please, i really need help.
Thank you
(ps : #air4x, thanks a LOT, even if i have another trouble, that showed me hox to override EditView. THANK YOU! )

Add to <body> tag of a cakePHP app

I have an app where I need to call some JS in the onLoad event of the BODY tag of two forms. However, I can't find how to modify the tag for just them. Does anyone know?
Frank
inkedmn certainly has provided the right answer for this case, but in general, you can "hand information up" like this:
(in views/controller/view.ctp)
$this->set('bodyAttr', 'onload="something"');
(in views/layouts/default.ctp)
<?php
if (isset($bodyAttr)) {
$bodyAttr = " $bodyAttr";
} else {
$bodyAttr = null;
}
?>
<body<?php echo $bodyAttr; ?>>
I often use it like this to add extra classes to a "top level element":
<?php
if (!isset($docClass)) {
$docClass = null;
}
?>
<div id="doc" class="<?php echo $docClass; ?>">
You don't need to modify the body tag to have Javascript execute when the page loads. You could just include something like this in your layout where appropriate:
(jQuery)
$("body").load(
function(){
// do stuff when the body element is loaded.
}
);
Or, if you want to have the code execute when the document.ready event fires:
$(function(){
// do stuff when the document is ready
}
);
Or, if you don't want to use jQuery, you could do something like this:
function doStuff(){
// whatever you want to happen when the load completes
}
window.onload = dostuff;
Good luck - and please clarify your question if this answer isn't satisfactory.
I do the following:
We apply $ bodyLoad in my body
<body <? = (isset ($ bodyLoad)? 'onload = \''. $ bodyLoad.' \'',''); ?> >
Already in my [action]. Ctp, I do the following:
<? php $ this-> set ('bodyLoad', 'field.focus ();');?>
If you want you can also put this code in the controller.
Good luck