I'm working on my own module. I realize I constantly need to manually type my module name in different places. Most popular usage is with drupal_get_path($type, $name) function (I have more then 10 of these in my code). Where $name is theme or module name. During that time I need to already change my module name 3 times. As you can surmise I also need change all module names hard-coded in my project. So I thought it would be nice to have some convenient function to grab this name automatically.
How can I get machine module name programmatically?
For example if you have your module in following directory..
sites/all/modules/my_module/
..then you can grab it in this way
drupal_get_current_module_name(); // return my_module
Generally, you should know by convention - if you have: sites/all/modules/my_module/ then the machine name of the module should match the folder name - my_module.
Virtually all contributed modules follow this convention, and you should too.
It is possible to have your .info and .module file not match the name of the folder, but this isn't correct.
If you are already executing code inside your module, you should already know the machine name of the module by virtue of the name of the file you're editing - unless you're trying to do something that I'm not understanding.
Edit: Since we've determined you're just trying to call your module's theme function, you don't actually need to know the name.
If you have:
/** Implements theme_table **/
function my_really_long_module_name_table() {}
Your function might get called like this:
theme('table');
There is a little more to it than that, but the theme engine will make a determination about which theme functions get called based on what is implementing them.
It sounds like you may want to read up on some of the basics of the Drupal theme system.
Here's a good start for learning the Drupal 6 theme layer: http://drupal.org/node/165706
I figure out something like this:
function get_current_module_name() {
return array_shift(explode('.', end(explode(DIRECTORY_SEPARATOR, __FILE__))));
}
but don't know is't the best way to do it..
UPDATE:
I see now it's better to use basename
$name = basename(__FILE__, '.module');
UPDATE 2:
I think if this is needed across whole module then it could be accessible via constant defined in the very beginning of the module e.g.:
define('MODULE_NAME', basename(__FILE__, '.module'));
Then you could use all the time in all your function like this:
drupal_get_path('module', MODULE_NAME);
Related
I am trying to give a shot to HMVC in Codeigniter. Here is my folder structure.
-ROOT
--APPLICATION
---MODULES
----Module_Email
-----Controllers
-----Models
-----Views
-----Assets
------JS
------CSS
------IMG
To render the Module i have to use
Module::run('Module_Email');
This method will output the rendered output, an example is given below
<script type="text/javascript" src="PATH/TO/EMAIL_MODULE/JS/JS_FILE.JS"></script>
<div data-module-name="Module_Email" class="Email_wrapper">
//RENDERED HTML CONTENT
</div>
Now here my problem start. Normally i would like to put all my resources to header. So when i call any module, its dependence need to be added in header instead of from where its get called.
I searched a lot but i couldn't find any good methods.
Please help.
Update
Currently i have a function on my header called get_assets() which will output predefined resources to header. But i cant say which modules is going to use in pages, so the system need to check which modules are used in this page, and if its used then its dependencies need to be added on header.
Seems like your main problem then is trying to figure out what modules were used.
Unfortunately as far as I can tell with the default Wiredesignz modular extension there is no way to access the module name unless you write some sort of hack to get at that data. The module being used is stored in the protected variable $module in the MX_Router class, however, there is no public method to allow you to get access to it. So your only choice would be to extend the class and create a public function.
Alternatively you could use a forked version of Wiredesignz implementation which I did which provides numerous other features including a public function to get at the $module variable. Using the forked version I wrote you could then use code such as this:
<?php $module_name = $this->router->fetch_module(); ?>
However, that will only record the last module you loaded, so you would still need to do work to store all the modules, and then have your function use this information to determine what assets to load. If I were doing something like you I would probably fork my version and then create an additional data structure to store every module that was loaded that you could then later get access to.
I don't think this is exactly what you were hoping for, but might be something to get you on the right track to finding a solution.
I added an array to the Module class to store the assets and two functions to store/retrieve the items. Here is the source (updated Modules.php)
# Register your assets
public static function register_asset( $asset )
{
if( in_array($asset,self::$assets) === FALSE )
{
self::$assets[] = $asset;
}
}
public static function assets()
{
return self::$assets;
}
and now you can register your assets like this inside your module
Modules::register_asset('myslider.js');
You can retrieve all your assets using
Modules:assets();
Which will return an array of assets that can be processed depending up on the situation.
I am using codeigniter for a project that is used by a variety of companies.
The default version of our software is up and running and works fine - however some of our customers want slightly different view files for their instance of the system.
Ideally what I would like to do is set a variable (for example VIEW_SUFFIX) and whenever a view file is loaded it would first check if there was a suffix version available if there was use that instead.
For example if the system had a standard view file called 'my_view.php' but one client had a VIEW_SUFFIX of 'client_1' - whenever I called $this->load->view('my_view') if the VIEW_SUFFIX was set it would first check if my_view_client_1 existed (and if it did use that) or if not use the default my_view.php.
I hope that my question is clear enough... If anyone has done this before or can think of a way to do it I would really appreciate it.
EDIT:
Ideally I would like a solution that works without me changing every place that I am calling the view files. Firstly because there are a few files that may want different client versions and also because the view files are called from a lot of controllers
I had a similar requirement for which I created a helper function. Among other things, this function can check for a suffix before loading the specified view file. This function can check for the suffix and check if the file exists before loading it.
Unfortunately, the file checking logic would be a bit brittle. As an alternative, you can implement a MY_Loader class that will override the basic CI_Loader class.
Something like this in your application/core/MY_Loader.php:
class MY_Loader extends CI_Loader {
protected function _ci_load($_ci_data)
{
// Copy paste code from CI with your modifications to check prefix.
}
}
Could you not do this
// some method of creating $client
// probably created at login
$_SESSION['client'] = 'client_1';
$client = (isset($_SESSION['client'])) ? $_SESSION['client'] : '';
$this->load->view("your_view{$client}", $data);
I want to override the guestbook functionality. To be exact, I want to override the action_form_save_entry() function on [mysite]/concrete5/core/controllers/blocks/guestbook.php
I've tried to override it these ways:
[mysite]/controllers/blocks/guestbook.php
[mysite]/core/controllers/blocks/guestbook.php
noe of them works. I can't find any way how to override that file. The documentation here and here doesn't show how to override that /core/ directory. Their forum never helps. Google result also just get misled with the 'core' keyword. All the result just take the 'core' meaning as just what's exist on the /concrete5/ directory, not the exact true /concrete5/core
Looks like that /concrete5/core/ directory appear only on the newer version. CMIIW.
Btw, maybe I should also tell you what I want to do with that function. Probably you have another workaround for this instead of simply overriding it. I want to add SMS notification functionality to it. So whenever someone submit a new comment, an SMS would be sent to the admin of a particular page.
Yes, the /concrete/core directory structure is new to 5.6. Tutorials and documentation on c5 can be ... lacking ... but in this case it's just a matter of them being behind a bit.
The "real" guestbook controller is at /concrete/blocks/guestbook/controller.php. You'll notice that it's just a shell of a class:
class GuestbookBlockController extends Concrete5_Controller_Block_Guestbook {}
The file that you referenced defines Concrete5_Controller_Block_Guestbook.
So, the solution is to override the real controller, not whatever it extends (ie, the file that you were looking at). Thinking in this way, it should be clearer that you need to create a file at /blocks/guestbook/controller.php. In fact, just copy the controller.php that I referenced above because you need to keep the (sometimes multiple) classes. Then, you can override the particular function. (Don't forget to call parent::action_save_form_entry()).
How to define variables in drupal module so that I can access those variables in that module from any function
Try variable_set() and variable_get()
Set the variable like that:
// I have assumed the variable name to be "the_name_of_the_variable"
variable_set("the_name_of_the_variable", "the value of the variable");
And then retrieve the value like that:
$my_variable = variable_get("the_name_of_the_variable", "a default value in case the variable has never been set before");
For every page load in Drupal all the .module files are loaded. But this is not the case for the inc files.
Inc files are loaded only when it is mentioned in the menu hook or they are explicitly mentioned in module file using module_load_include
// Load node.admin.inc from the node module.
module_load_include('inc', 'node', 'node.admin');
I think this pretty much answers your question. So you should define your variables as global in these files.
By your question if you mean that the scope of the functions defines in your module also should be limited to your module only, then I don't think there is any solution as of now. But at-least the above method will make sure that your variables are not loaded, when your module is not performing any actions.
I've got a Zend-Framework application. I'm using the module-structure which Zend_Controller_Frontprovides. Here is a small excerpt from my directory-structure (only the important parts for this question):
root-directory
- modules
- blog
- views
- scripts
- index_index.phtml
- views
- pagination_control.phtml
As you can see I've got view-scripts that are specific to a module/controller/action. These views are located in the corresponding path (in this case like modules/blog/views. I've also got a more general view-directory located in the root-direcetory of my application.
What I am doing now is to call the PaginationControl-ViewHelper in modules/blog/views/scripts/index_index.phtml. This View-Helper however renders a partial-view, as you know. The ViewHelper tries to locate the partial-view within the same directory (meaning modules/blog/views/scripts. Since I want to use the same view-partial-script (pagination_control.phtml) in different modules I want to make this view-partial accessable from each module. So I want to put that file in the general views-folder in the root-directory.
However this doesn't work. The ViewHelper always looks for the view-script in the corresponding module-folder.
Anyone can help to make it accessable from my general views-directory?
As you can see here, since ZF 1.6.2 pagination control can take an array instead of a string for the partial argument, and in this array you set 1st the name of the partial and in 2nd the module name. This is still undocumented.
Using an array you can specify a module ('common'?) for the partial to use.
The real call will be (with $partial your 3rd argument to the paginationControl() view helper ):
$this->view->partial($partial[0], $partial[1], $pages);
This is usefull if you have a 'common' module.
Now here you are using a shared folder. You shoudl have installed it as a shared folder for your Zend_View this way (in a Boostrap or ressource code):
$view->addScriptPath("/root-directory/views");
or better:
$view->addScriptPath("/root-directory/views/partials");
And then you should'nt be required to specify any module directory. Zend_View should always check for a partial in this folder.