How and where to write function to use in layout(main.php) in yii2 basic - layout

previously i made a navigation bar in a view page for which i wrote the function in corresponding controller but now i have to put this in main file (layout). But now i don't know where to write the function.
also i have to pass two variable to the layout file through the function that will contain the value of navigation bar.
I have already tried some method but it allows me to return only on value.
Basically i want to know that where can i write the below function to use it in main layout of yii2 basic
public function actionMenutest()
{
$query = new Query;
$data= $query->select('name,id')
->from('menu')->all();
$query2 = new Query;
$data2= $query2->select('name,menu_id')
->from('submenu')->all();
return $this->render('menutest',[
'data'=>$data, 'data2'=>$data2
]);
}

You can use EVENT_BEFORE_RENDER for this purpose. For advanced app the below code need to go into common\config\bootstrap.php file.
use yii\base\Event;
use yii\base\View;
Event::on(View::className(), View::EVENT_BEFORE_RENDER, function() {
$query = new Query;
$data= $query->select('name,id')
->from('menu')->all();
$query2 = new Query;
$data2= $query2->select('name,menu_id')
->from('submenu')->all();
Yii::$app->view->params['data'] = $data;
Yii::$app->view->params['data2'] = $data2;
});
Then in your main layout you can use your model as:
$data= $this->params['data'];
$data2= $this->params['data2'];
I have not used basic template as yet. But you can try the following:
Create a bootstrap.php file in config folder.
After that update the web/index.php file. Put the below code in that:
require(__DIR__ . '/../config/bootstrap.php');
Then put the above code in bootstrap.php file. Try it and let me know if you need any more help.

Related

How do I remove role="search" from the form-tag in drupal?

I am new to Drupal. I have developed one site . But in WCAG 2.0 testing I was getting following problem: Element 'form' does not need a 'role' attribute. How do I achive this ? Please Help...
Thanks.
Here is my source code:
enter image description here
You can do that by using hook_form_alter. You need to try this code with your custom module.
function hook_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'search_block_form') {
$form["#attributes"]["role"] = "";
//Or
unset($form["#attributes"]["role"]);
}
}
You need to create a custom module at 'sites/all/modules' directory and in the .module file you need to write this function replacing the hook with module name.
For example, create a custom module with the name custom. See this article if needs help. In the modules's custom.module file write the following function:
function custom_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'search_block_form') {
$form["#attributes"]["role"] = "";
//Or
unset($form["#attributes"]["role"]);
}
}
Hope that helps!

How to override template file item-list.html.twig for field_slider_images in Drupal 8?

I want to override the item listing template file core/themes/classy/templates/dataset/item-list.html.twig for listing the fields field_slider_images as well as field_blog_tags respectively of their's multiple values of the field.
I have selected "Unordered List" in the view.
Please do check the attached image.
I have created following files :
item-list--field-blog-tags.html.twig
item-list--field-slider-images.html.twig
But, this is not rendered for the listing of the fields.
When I have created item-list.html.twig then only it will access.
However, both fields have different data to style and I am not able to get the current field name which is loading it's data in item-list.html.twig.
Had a brief look at this and it doesn't seem that 'item-list' to have suggestions, which is quite unfortunate.
In this situation there are two options:
Create your own suggestion which would accomplish exactly what you need.
You'll have to do something like this:
/
/*add new variable to theme with suggestion name*/
function hook_theme_registry_alter(&$theme_registry) {
$theme_registry['item_list']['variables']['suggestion'] = '';
}
//send a value to newly added variable to use it build the suggestion
function hook_ENTITY_TYPE_view(array &$build, $entity, $display, $view_mode) {
//add condition here if field exists or whatever, do the same for other field
$build['field_slider_images']['#suggestion'] = 'field_slider_images';
}
//use newly added variable to build suggestion
function hook_theme_suggestions_THEME_HOOK(array $variables) {//THEME_HOOK=item_list
$suggestions = array();
if(isset($variables['suggestion'])){
$suggestions[] = 'item_list__' . $variables['suggestion'];
}
return $suggestions;
}
Now you should be able to use item-list--field-slider-images.html.twig
Second option is to do what others in core did: use a new theme
function hook_ENTITY_TYPE_view(array &$build, $entity, $display, $view_mode) {
//add condition here if field exists or whatever, do the same for other field
$build['field_slider_images']['#theme'] = array(
'item_list',
'item_list__field_slider_images',
);
}

Making jslink target specific list

Background
I got a page where I’m showing two list views from two separate lists which both have Custom List as their ListTemplate. They got their separate jslink file cause I don’t want them to look alike.
Problem
The js link file targets both listviews since they use the same Template.
Code
(function () {
var listContext = {};
listContext.Templates = {};
listContext.ListTemplateType = 100;
listContext.Templates.Header = "<div><ul>";
listContext.Templates.Footer = "</ul></div>";
listContext.Templates.Item = LinkTemplate;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(listContext);
})();
Question
Is there any way to make the js only target a specific list?
Ended up going with Paul Hunts solution that he writes about on myfatblog.co.uk. http://www.myfatblog.co.uk/index.php/2013/09/listview-web-part-issues-with-jslink-and-display-templates-a-solution/
The script ended up looking like this and I pasted it into the jslink function where I define what listContext to override.
// Override the RenderListView once the ClientTemplates.JS has been called
ExecuteOrDelayUntilScriptLoaded(function(){
// Copy and override the existing RenderListView
var oldRenderListView = RenderListView;
RenderListView = function(ctx,webPartID)
{
// Check the title and set the BaseViewId
if (ctx.ListTitle == "List")
ctx.BaseViewID = "list";
//now call the original RenderListView
oldRenderListView(ctx,webPartID);
}
},"ClientTemplates.js");

Backbone.js: pass model to sub-view by reference

UPDATE: As it turns out, i had a leftover this.model = new MasterModel(); in my subViews initialize() function.
I am trying to separate my huge view to smaller views and so I have created a "master" layout view that attaches to itself some subviews and passes it's model to them.
However, it seems that when my sub-view updates the model, these changes are not reflected on the "master" view's model.
Here's what I am trying to do:
var master = new MasterModel();
var masterView = new MasterView({model:master});
Inside of the masterView initialize() function I do this:
function: initialize() {
this.subView = new subView({model:this.model});
}
And the code that changes the model in subView is this:
function: setCurrency() {
this.model.set({ currency: this.$('.currency').val() });
}
Maybe I am doing something completely wrong here?
How many things have class "currency" are on your page?
I don't think this.$('.currency').val() means what you think it means. I think you're wanting something like $(this.el).find('.currency').val() (are you using 0.9.1? then you could shorten that to $el.find('.currency').val() ). What you have will always grab the first item on the page with class "currency". this.$ is just a convenience reference to what would normally be the global Zepto or jQuery object. Hence, my question.
Edit: awaiting response to clarification question.
Make your model global so instead of:
var master = new MasterModel();
use
window.master = new MasterModel();
and then pas this to your subViews
function: initialize() {
this.subView = new subView({model:window.master});
}

Appending Text to the body field in Drupal

I am trying to append a string to the body field of a CCK node after it has been submitted or edited. However, I'm having trouble working with the body field in the form alter. My initial attempt was to modify the body field in the submit handler by using the .operator to append a string to the body field.
//Calling this submit function to add string to body.
function appendToBody_submit_function($form, &$form_state) {
$form_state['values']['body'] = array('0' => array('value' => $form['#body'])) . $stringToAppend;
}
However, I can't get this to work, and I'm not sure it's the right way. I am new to Drupal, Can someone point me in the right direction? Should I be using node_api for this?
I assume that you add your custom submit callback to the forms #submit array via hook_form_alter().
If you add it before any other entry in that array (as opposed to just appending it), your callback should be called before the standard submit function. That way, all you need to do is adjust the $form_state['values']['body'] content 'in place', and it will be picked up (and subsequently saved) on further processing by the standard submit callback implicitly:
/**
* Implementation of hook_form_alter()
*/
function yourModule_form_alter(&$form, $form_state, $form_id) {
// Is this a node edit form?
if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] .'_node_form' == $form_id) {
// Yes, add custom submit handler *before* already existing ones
array_unshift($form['#submit'], 'appendToBody_submit_function');
}
}
// Custom submit function to add string to body.
function appendToBody_submit_function($form, &$form_state) {
$form_state['values']['body'] = $form_state['values']['body'] . $stringToAppend;
}
I recommend installing the Devel module so you can easily print out the contents of $form_state by placing dpm($form_state); in your method body. I usually start with that to make sure the values are where/what I expect.
// Replace "hook" in the function name with the name of your module.
function hook_submit($form, &$form_state) {
// dpm($form_state); // Debug code to view the contents of $form_state.
$body = $form_state['values']['body'] . ' new string to append';
// Place code to save this data to your database here.
}

Resources