Moodle standard_end_of_body function location? - php

I'm trying to customize the rendering of the standard_end_of_body(), but I can't seem to find the proper function.
I found the abstract function in /lib/outputrenderers.php, but not the actual theme implementation. In the code it is mentioned that it should be in the theme renderer, so I checked into every renderer, as well as the themes mine is based in (bootstrap and Elegance), but so far, nada.
So I'm very much open to any suggestions!
Thanks

In /theme/yourtheme/renderers/php
add this
class theme_yourtheme_core_renderer extends core_renderer {
public function standard_end_of_body_html() {
// Optionally add the parent html.
$output = parent::standard_end_of_body_html();
$output .= 'my stuff';
return ($output);
}
alternatively, you can also add footer html to the setting additionalhtmlfooter
via site admin -> appearance -> additional html
or direct to /admin/settings.php?section=additionalhtml

Related

override a function wrapped with if (!function_exists)

I'm using "Advanced Scripts plugin" to modify a function of other plugin, the fuction I'm trying to modify is wrappd with if( !function_exists('some_function') ).
the function inside the plugins is like this
if( !function_exists('send-invoice') ){
function send-invoice(){
//The Plugin Invoice
}
}
This is what I did
function send-invoice(){
//My Custom Invoice
}
add_action('init', 'send-invoice');
How can I make sure that my code runs before the plugin codes?
The plugin load before the theme, I tried plugin-loaded hook but nothing changed
You can to use the anonymous function for example:
add_action('init', function() {
//code here
});
More detail is here
Or use another hook muplugins_loaded:
function send-invoice(){
//My Custom Invoice
}
add_action('muplugins_loaded', 'send-invoice');
If nothing else work for you you can create a custom plugin, name it something like "aaamyplugin" and just insert there a single .php file with the function you are trying to override. This is the easiest (not cleanest) way to make sure your code overrides the plugin functions.
The reason for this is because Wordpress plugin loading order is simply alphabetical, that means that everything named before the plugin you are trying to override, get loaded first.
The cleanest way would be to look into the source code of the plugin to understand how it does what it does. Like: when does it load that file that contains the function you are trying to override? That's the important question to answer if you want to go with clean way

Silverstripe fulltextsearch on custom field

I'm using Silverstripe FullTextSearch. My interrogation is how search in a custom field and show results. There is code write in index.md :
File: mysite/code/MyIndex.php:
<?php
class MyIndex extends SolrIndex {
function init() {
$this->addClass('MyPage');
$this->addFulltextField('Description');
}
}
In Page.php
class Page_Controller extends ContentController {
private static $allowed_actions = array('search');
public function search($request) {
$query = new SearchQuery();
$query->search($request->getVar('q'));
return $this->renderWith('array(
'SearchResult' => singleton('MyIndex')->search($query)
));
}
}
When I'm trying to search some words from description field, no results are found... Suggestions?
In my experience FullTextSearch has been frustrating and problematic. I am willing to be corrected, but I feel like the devs are moving away from it in place of using SearchFilters (https://docs.silverstripe.org/en/3.1/developer_guides/model/searchfilters/).
If it is helpful at all I wrote a module that allows for custom searching and displaying the results in a custom controller. It isn't as efficient as FullTextSearch but works pretty well (https://github.com/i-lateral/silverstripe-searchable).
I did originally try to write this module using FullTextSearch, but I just couldn't get it working.
Well, I have found a solution. FullTextsearch module always search in $Title, $MenuTitle and $Content. Instead of using $Content for my content, I use $ContentPage variable. All DataObjects and other variables must must added like bellow.
Example :
$this->Content = $this->ContentPage." ".$this->Variable1." ".$this->Variable2." ".$dataobject;
In the example, all variables and dataobject in the page is searchable throught $Content. That's not a perfect solution, but works.

How to attach a module to a drupal article?

I have a php function in a drupal module. This function outputs some random text. I want to attach this module to a Drupal article so that each time someone creates an article, random text will appear in it. How can I do this?
The solution here is to use a Drupal hook function to modify the content of the node.
Assuming your module is called "my_module":, you'd add another function to your my_module.module file as follows:
function my_module_node_view(&$node, $view_mode, $langcode) {
// We want to make sure this only applies to nodes of the content type "article"
if ($node->type == "article") {
// Append the output of your function to the body; this could easily be added to any other field as well
$node->body['und'][0]['value'] = $node->body['und'][0]['value'] . my_module_random_text_function();
}
}
Note: the $node object is automatically passed to this hook function by reference, so you don't need to worry about returning anything from the function.
If you wanted to apply this at the theme layer, you could use the theme_preprocess_node hook in your theme's template.php file, but your original question suggested that you'd already gone down the plugin route.

what is the use of classes_array in drupal7 template.php

in template.php many times they used classes_array..am not getting the meaning and why they using,..what is the purpose of classes_array and when we have to use that in drupal7 .tpl.php
example code:
if(in_array('administrator',array_values($variables['user']->roles)))
{
$variables['classes_array'][]="debug";
}
$variables['classes_array'] is used in preprocess functions. It adds classes to be used in rendering the element to be processed. In your example, a class named "debug" will be added to the html container of the rendered element: if the actual code is
function <YOUR THEME>_preprocess_html(&$variables) {
if (in_array('administrator',array_values($variables['user']->roles))) {
$variables['classes_array'][]="debug";
}
}
your theme will output a body tag like
<body class='debug [...OTHER CLASSES...]'>
for users with administrator role.
You can also add classes to nodes, or other kind of elements for which a preprocess hook is available. E.g. you could write a node preprocess function:
function <YOUR THEME>_preprocess_node($variables) {
$classes_array[] = 'my-class';
}
if you wanted to add 'my-class' to every node of your site.
In general, you will not find $classes_array among the defined variables in tpl.php files. Your theme will, most of the times, implode them in a $classes variable. It must be noted, however, that a kind of confusion arised over time, so different themes may use $classes_array, $attribute_array, $classes, $attributes['class'] and so on for the same purpose, so you should check your theme's documentation to find out what suits your case.

Where in Magento is the homepage pulled?

I'm assuming it's one of the app layout files - I want to write a hook in my mobile template to pull a different CMS homepage.
Edit: To clarify, I want to achieve having a different cms page pulled for the hompage of a mobile version of the store vs. the desktop version. Since you can only set one default CMS page in magento admin, seems like there needs to be some custom coding in the mobile template files.
One of the things I love about Magento is the ability to accomplish a lot of things, just by playing with layout files.
I'll refer to Alan Storm's image to illustrate how I accomplished this exact task without having to change code (I hope you don't mind Alan).
As you can see with the image above, the Full Action Name is cms_index_index. You can find this information with debugging tools, like Commerce Bug.
As we have the action name, we can change the layout files to point to a mobile-specific home page. In this method the mobile-specific home page is actually a static block.
Once you have set up your mobile-specific content, you can add the following to your mobile template local.xml file, to use this block for your home page:
<cms_index_index>
<block type="cms/block" name="cms_page"><action method="setBlockId"><block_id>mobile_home</block_id></action></block>
</cms_index_index>
In this case I have set up a mobile_home static block. It will use the same layout name as the desktop home page, but this has already been overridden in the mobile template.
This may not be the best way, but it doesn't involve code changes.
It's probably not as straight forward as you'd like, but here's how this works.
The request for the homepage is routed to the indexAction method of the Mage_Cms_IndexController class.
If you take a look at the indexAction method you can see Magento uses the renderPage method of the cms/page helper object to render the contents of the page
#File: app/code/core/Mage/Cms/controllers/IndexController.php
public function indexAction($coreRoute = null)
{
$pageId = Mage::getStoreConfig(Mage_Cms_Helper_Page::XML_PATH_HOME_PAGE);
if (!Mage::helper('cms/page')->renderPage($this, $pageId)) {
$this->_forward('defaultIndex');
}
}
The $pageId is pulled from Magento's system configuration, and is the URL identifier of the CMS page.
If you hop to the renderPage method
#File: app/code/core/Mage/Cms/Helper/Page.php
public function renderPage(Mage_Core_Controller_Front_Action $action, $pageId = null)
{
return $this->_renderPage($action, $pageId);
}
it wraps the call to the protected _renderPage method. If you hop to THAT method, the page loading code is the following portions.
#File: app/code/core/Mage/Cms/Helper/Page.php
protected function _renderPage(Mage_Core_Controller_Varien_Action $action, $pageId = null, $renderLayout = true)
{
$page = Mage::getSingleton('cms/page');
//...
if (!$page->load($pageId)) {
return false;
}
//...
}
This loads the CMS Page object for the homepage. Notice the model is a singleton, which means other code that instantes the singleton later will have the same page. After this, standard Magento page rendering happens. Possibly relevant to your interests, the content layout blocks end up looking like this
Meaning the block HTML for the CMS page is rendered by the following code in Mage_Cms_Block_Page
#File: app/code/core/Mage/Cms/Helper/Page.php
protected function _toHtml()
{
/* #var $helper Mage_Cms_Helper_Data */
$helper = Mage::helper('cms');
$processor = $helper->getPageTemplateProcessor();
$html = $processor->filter($this->getPage()->getContent());
$html = $this->getMessagesBlock()->toHtml() . $html;
return $html;
}
The getPage method instantiates the same singleton we mentioned above. The other code is what replaces CMS page {{...}} directives with their actual content.
If I was approaching this project, I'd consider a class rewrite for the Mage_Cms_Model_Page object that looks something like this.
public function load($id, $field=null)
{
if( ... is mobile site ... AND ... $id is for the home page ...)
{
$id = ... ID of the mobile site, hard coded or pulled from custom config ...;
}
return parent::load($id, $field);
}
There's also the cms_page_render event which fires after the page has loaded in the _renderPage method. You could try reloading the passed in page object with a different ID in the observer. You could also consider something in the model_load_after or model_load_before events — although that gets trickier to do since you can't directly change the ID.
For code that's not going to leave a single client's system, I usually opt for the rewrite these days, since it's quicker (less expensive for clients) and has less complications (i.e. getting at and changing the information you need) during development. The trade-off is a possible future conflict with someone else who's rewriting the class.
Your milage/philosophy may vary.
Good luck!

Categories