I want to ask you how to change a colour of text in navbar (where is the Home, About,...) in Yii2 framework basic template? I've tried so many things but nothing worked. Thank you for reply!
In the case of the text of the <a> element (the link ) of navbar the color is defined inside the bootstrap.min.css.
.navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus {
background-color: #1a242f;
color: #ffffff;
}
Then if you want to change the css then you must change the bootstrap.css and the minimize ..
A simple way is change directly the style in the layout ..
changing directly the style of the item using options for the li tag and linkOption for the related link
<?php
NavBar::begin([
'brandLabel' => 'Name',
'brandUrl' => Yii::$app->homeUrl,
'options' => [
'class' => 'my-navbar navbar-fixed-top',
],
]);
echo Nav::widget([
'options' => ['class' => 'navbar-nav navbar-right'],
'items' => [
['label' => 'Home', 'url' => ['/site/index'], 'options' => ['style' => 'background-color: #F00;']],
['label' => 'About', 'url' => ['/site/about']], 'linkOptions' => ['style' => 'color: #000;']],
Yii::$app->user->isGuest ?
['label' => 'Login', 'url' => ['/site/login']] :
[
'label' => 'Logout (' . Yii::$app->user->identity->username . ')',
'url' => ['/site/logout'],
'linkOptions' => ['data-method' => 'post']
],
],
]);
NavBar::end();
?>
Not
'options' => ['style' => 'color: #000;']]
but
'linkOptions' => ['style' => 'color: #000;']]
linkOptions works! Color changed
Instead of using 'linkOptions' => ['style' => 'color: #000;']]
I did 'linkOptions' => ['class' => 'myCssClass']]
This worked for me
Related
I have created a new module to add a new step to the signup process to get the user's phone number. Everything works fine, except the fact that after the signup, I need to grab the phone number I have received in my specific step and add it to the users table. For this purpose, I have added a hook in my module's manifest file as follows to be triggered after signup completes:
<?php
return array(
'package' =>
array(
'type' => 'module',
'name' => 'advancedsmsplugin',
'version' => '4.0.0',
'sku' => 'com.company.sms',
'path' => 'application/modules/Advancedsmsplugin',
'title' => 'Advanced SMS Plugin',
'description' => 'Advanced SMS Plugin',
'author' => 'Company Ltd.',
'callback' =>
array(
'class' => 'Engine_Package_Installer_Module',
),
'actions' =>
array(
0 => 'install',
1 => 'upgrade',
2 => 'refresh',
3 => 'enable',
4 => 'disable',
),
'directories' =>
array(
0 => 'application/modules/Advancedsmsplugin',
),
'files' =>
array(
0 => 'application/languages/en/advancedsmsplugin.csv',
1 => 'application/modules/User/Form/Signup/Phone.php',
2 => 'application/modules/User/Plugin/Signup/Phone.php',
),
),
'hooks' => array(
array(
'event' => 'onUserCreateAfter',
'resource' => 'User_Plugin_Phone',
),
),
);
?>
I have also created the class that I named in the hook namely User_Plugin_Phone and saved it as application/modules/user/Plugin/Phone.php.
class User_Plugin_Phone extends Core_Plugin_Abstract {
public function onUserCreateAfter($event) {
echo '<script>console.log("Inside User_Plugin_Phone::onUserCreateAfter");</script>';
echo '<script>alert("Inside User_Plugin_Phone: onUserCreateAfter");</script>';
$payload = $event->getPayload();
}
}
But, logs show that the hook is not triggered at all. I have checked this and this, and I think I have followed them correctly. Any ideas why this does not work]?
I have an application with three modules with several controllers in each module. All these controllers work fine. But now, I'm trying to create a new controller in my Privado module, in this route /domain/privado/querys/querys.
I have created the controller, her view, and config in module.config.php
'privado/querys' => array(
'type' => 'Literal',
'options' => array(
'route' => '/privado/querys',
'defaults' => array(
'__NAMESPACE__' => 'Privado\Controller',
'controller' => 'Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
//'route' => '/[:controller[/:action[/:id]]]',
'route' => '/[:controller[/:action][/:id/:system]]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]*',
'system' => '[a-zA-Z][a-zA-Z0-9_-]*'
//'system' => '[0-9]*'
),
'defaults' => array(
),
),
),
),
),
'controllers' => array(
'invokables' => array(
'Privado\Controller\Index' => Controller\IndexController::class,
'Privado\Controller\Usuario' => Controller\UsuarioController::class,
'Privado\Controller\Profile' => Controller\ProfileController::class,
'Privado\Controller\Sistemas' => Controller\SistemasController::class,
'Privado\Controller\UnidadesServicio' => Controller\UnidadesServicioController::class,
'Privado\Controller\Metales' => Controller\MetalesController::class,
'Privado\Controller\Pases' => Controller\PasesController::class,
'Privado\Controller\Estado' => Controller\EstadoController::class,
'Privado\Controller\QuerysController' => Controller\QuerysController::class,
'Privado\Controller\TestController' => Controller\TestController::class
),
),
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'privado/index/index' => __DIR__ . '/../view/privado/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
/*
* Con este array de parĂ¡metros permitimos enviar datos y no mostrar vista
*/
'strategies' => array(
'ViewJsonStrategy',
),
),
And the controller returns me the layout from another module The controller returns me the layout from the Publico module. I just understand what I missed.
Edit 1:
I've got the wrong layout and this message on the screen:
A 404 error occurred Page not found.
The requested controller could not be mapped to an existing controller
class.
Controller:
Privado\Controller\Querysasdad(resolves to invalid controller class or alias: Privado\Controller\Querysasdad)
No Exception available
This is the error that I've got too, If I write a controller which doesn't exists in the url !
I have create another controller in other module following the same steps: create the controller, create the view, config module.config.php and works fine.
I have found my terrible error :
In my module.config.php I have in invocables ...
'Privado\Controller\QuerysController' => Controller\QuerysController::class,
'Privado\Controller\TestController' => Controller\TestController::class
I fix the problema, remove "Controller" from "Privado\Controller\QuerysController" and "Privado\Controller\TestController"
'Privado\Controller\Querys' => Controller\QuerysController::class,
'Privado\Controller\Test' => Controller\TestController::class
Can someone help me to set up a layout for the administration module and set up a layout for the application module ? . In the image below you can see my folder structure:
This is the content of my module.config.php from the administration module:
<?php
return array(
'controllers' => array(
'invokables' => array(
'Administration\Controller\Admin' => 'Administration\Controller\AdminController',
),
),
// The following section is new and should be added to your file
'router' => array(
'routes' => array(
'album' => array(
'type' => 'segment',
'options' => array(
'route' => '/administration[/:action][/:id]',
'constraints' => array(
'action' => '[a-zA-Z][a-zA-Z0-9_-]*',
'id' => '[0-9]+',
),
'defaults' => array(
'controller' => 'Administration\Controller\Admin',
'action' => 'index',
),
),
),
),
),
'view_manager' => array(
//'base_path' => 'http://www.attila-naghi.com/',
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout2.phtml',
// 'administration/admin/index' => __DIR__ . '/../view/administration/admin/index.phtml',
// 'error/404' => __DIR__ . '/../view/error/404.phtml',
// 'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
DIR . '/../view',
),
),
)
?>
here i set up the layout. But for some reason if i access the application module, it loads the layout from the administration module. WHY ?
this is the content of the module.config.php file from the application module:
return array(
'router' => array(
'routes' => array(
'home' => array(
'type' => 'Zend\Mvc\Router\Http\Literal',
'options' => array(
'route' => '/',
'defaults' => array(
'controller' => 'Application\Controller\Index',
'action' => 'index',
),
),
'may_terminate' => true,
'child_routes' => array(
'default' => array(
'type' => 'Segment',
'options' => array(
'route' => '[:controller[/:action]][/:param1]',
'constraints' => array(
'controller' => '[a-zA-Z][a-zA-Z0-9_-]*',
'action' => '[a-zA-Z][a-zA-Z0-9_-]*'
),
'defaults' => array(
'action' => 'index',
'__NAMESPACE__' => 'Application\Controller',
// 'param1' => 'tralala'
)
)
)
)
),
),
),
'service_manager' => array(
'abstract_factories' => array(
'Zend\Cache\Service\StorageCacheAbstractServiceFactory',
'Zend\Log\LoggerAbstractServiceFactory',
),
'aliases' => array(
'translator' => 'MvcTranslator',
),
),
'translator' => array(
'locale' => 'en_US',
'translation_file_patterns' => array(
array(
'type' => 'gettext',
'base_dir' => __DIR__ . '/../language',
'pattern' => '%s.mo',
),
),
),
'controllers' => array(
'invokables' => array(
'Application\Controller\Index' => 'Application\Controller\IndexController',
'Application\Controller\Create' => 'Application\Controller\CreateController',
'Application\Controller\Blog' => 'Application\Controller\BlogController',
'Application\Controller\Portofolio' => 'Application\Controller\PortofolioController',
'Application\Controller\User' => 'Application\Controller\UserController',
),
),
'view_manager' => array(
'base_path' => 'http://www.attila-naghi.com/',
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_map' => array(
'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
'application/index/index' => __DIR__ . '/../view/application/index/index.phtml',
'error/404' => __DIR__ . '/../view/error/404.phtml',
'error/index' => __DIR__ . '/../view/error/index.phtml',
),
'template_path_stack' => array(
__DIR__ . '/../view',
),
),
// Placeholder for console routes
'console' => array(
'router' => array(
'routes' => array(
),
),
),
);
and this is the application.config.file content:
return array(
// This should be an array of module namespaces used in the application.
'modules' => array(
'Application',
'Administration'
),
......
You have to change layout from the controller. just specify this code above the ViewModel
$this->layout('administration/admin/index');
The configs of all modules are merged into a single config. The last loaded module will overwrite the layout from the first module. You can use the module below to set layout per module.
https://github.com/EvanDotPro/EdpModuleLayouts
I have recently found a way to do it (someone else's solution).
Add this to your module.config.php (in my case the module is called Album, this is based on the demo application of ZF2):
'module_layouts' => array(
'Album' => 'layout/layout.phtml'
),
The other necessary change needs to be done in the main Module.php file (add this onBootstrap method there and edit as may be needed):
public function onBootstrap($e) {
$e->getApplication()
->getEventManager()
->getSharedManager()
->attach('Zend\Mvc\Controller\AbstractController', 'dispatch',
function($e) {
$controller = $e->getTarget();
$controllerClass = get_class($controller);
$moduleNamespace = substr($controllerClass, 0, strpos($controllerClass, '\\'));
$config = $e->getApplication()->getServiceManager()->get('config');
if (isset($config['module_layouts'][$moduleNamespace])) {
$controller->layout($config['module_layouts'][$moduleNamespace]);
}
}, 100);
}
As requested here is my way for different layouts. This was not my idea but since i cannot find the source i will post the code here. If someone does know please add the URL in comment and i will include it in the answer. If you read the sources i gave you in the other question and the above answers i am sure will understand what is happening here.
Module.php
use Zend\ModuleManager\ModuleManager;
> > public function init(ModuleManager $moduleManager)
> {
> $sharedEvents = $moduleManager->getEventManager()->getSharedManager();
> $sharedEvents->attach(__NAMESPACE__, 'dispatch', function($e) {
> // This event will only be fired when an ActionController under the MyModule namespace is dispatched.
>
> $controller = $e->getTarget();
$controller->layout('backofficeLayout');
>
> }, 100);
>
>
>
> }
module.config.php
'view_manager' => array(
'display_not_found_reason' => true,
'display_exceptions' => true,
'doctype' => 'HTML5',
'not_found_template' => 'error/404',
'exception_template' => 'error/index',
'template_path_stack' => array(
'backoffice' => __DIR__ . '/../view',
),
'template_map' => array(
'backofficeLayout' => __DIR__ . '/../view/layout/myaccount-backoffice.phtml',))
I have just noticed that is better to use custom name for each of the layout in your layout folder. Instead of using layout.phtml use layout-mymodulename.phtml. It worked better along with the previously highlighted points.
What I'm trying to accomplish
I'm building a favorites module and I need the ability to:
Select from a dropdown, hardcoded list of options
Have it save to the database
Upon refreshing the page, remove the already saved option from the list of options so it may not be added again
The third part is where I am unsure of how to proceed.
How my code is set up
This is my form:
/*
* Implentation of hook_form().
*/
function f25_favorites_form() {
$listOfPaths = f25_favorites_listOfPaths();
$form['path_options'] = array(
'#type' => 'value',
'#value' => array(
'default' => $listOfPaths['default']['#title'],
'concierge' => $listOfPaths['concierge']['#title'],
'concierge/add' => $listOfPaths['concierge/add']['#title'],
'survey-questions' => $listOfPaths['survey-questions']['#title'],
'survey-questions/add' => $listOfPaths['survey-questions/add']['#title'],
'profiles' => $listOfPaths['profiles']['#title'],
'profiles/add' => $listOfPaths['profiles/add']['#title'],
'statistics' => $listOfPaths['statistics']['#title'],
)
);
$form['path'] = array(
'#type' => 'select',
'#title' => t('Select Page'),
'#required' => TRUE,
'#weight' => '11',
'#options' => $form['path_options']['#value'],
);
$form[submit] = array(
'#type' => 'submit',
'#weight' => '1000000',
'#value' => t('Add')
);
return $form;
}
The name of the paths/options are called via a reference array:
/*
* List of Paths to add to favorites
*/
function f25_favorites_listOfPaths() {
$list = array();
$list = array(
'default' => array(
'#title' => t('Add to favorites'),
),
'concierge' => array(
'#title' => t('Concierge'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/concierge.png',
'#desc' => t('Concierge'),
),
'concierge/add' => array(
'#title' => t('New Concierge'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/concierge.png',
'#desc' => t('Concierge > Add'),
),
'survey-questions' => array(
'#title' => t('Survey Questions'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/survey-questions.png',
'#desc' => t('Current Survey Questions'),
),
'survey-questions/add' => array(
'#title' => t('New Survey Question'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/survey-questions.png',
'#desc' => t('Survery Question > Add'),
),
'profiles' => array(
'#title' => t('Profiles'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/profiles.png',
'#desc' => t('User Profiles'),
),
'profiles/add' => array(
'#title' => t('Add Profile'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/profiles.png',
'#desc' => t('Profiles > Add'),
),
'statistics' => array(
'#title' => t('Statistics'),
'#image' => drupal_get_path('module', 'f25_favorites').'/img/statistics.png',
'#desc' => t('Performance Stats'),
),
);
return $list;
}
And all this is what grabs the data on the databse:
/*
* Write Form data to database
*/
function f25_favorites_form_submit($form, &$form_state){
global $user;
$listOfPaths = f25_favorites_listOfPaths();
$selected = $form_state['values']['path'];
$data = array(
'uid' => $user->uid,
'path' => $selected,
'title' => $listOfPaths[$selected]['#title'],
'weight' => 10,
'timestamp' => time(),
);
drupal_write_record(f25_favorites, $data);
}
Possible Solutions
I've been told that I could used hook_form_alter() in order to modify my array but I am unsure as to when I should be comparing the db_query to my array and how to modify the differences accordingly.
I hope I've done a good job explaining what I'm try to do.
What would be the best way to accomplish this?
Instead of writing every response in f25_favorites_listOfPaths(), shouldn't you get them from the database?
You can then change whatever you want in the submit function to the database so that you don't fetch again the previously selected answer.
Example :
function f25_favorites_listOfPaths() {
return variable_get('f25_favorites_array_' . $user->uid, array(
// your $list array
));
}
function f25_favorites_submit_form($form, &$form_state) {
// your stuff already
drupal_write_record(f25_favorites, $data);
// Now what I propose you to do :)
variable_set('f25_favorites_array_' . $user->uid, array(
// new $list array without the favorite selected
));
}
The use of variable_get/set() should of course be replaced by your own table if you have too much datas.
P.S. : hook_form() does not exist :)
I have not been able to get drupal_get_form to pass on the node data. Code snippets are below. The drupal_get_form documentation (api.drupal.org) states that it will pass on the extra parameters. I am basing the node data not being passed because (apparently) $node['language'] is not defined in hook_form which causes $form['qqq'] not to be created and thus the preview button shows up.
My goal here is that the preview button show up using path "node/add/author" but doesn't show up for "milan/author/add". Any alternative methods for achieving this goal would be helpful but the question I want answered is in the preceding paragraph. Everything I've read indicates that it should work.
This menu item
$items['milan/author/add'] = array(
'title' => 'Add Author',
'page callback' => 'get_author_form',
'access arguments' => array('access content'),
'file' => 'author.pages.inc',
);
calls this code
function get_author_form() {
//return node_form(NULL,NULL);
//return drupal_get_form('author_form');
return author_ajax_form('author');
}
function author_ajax_form($type) {
global $user;
module_load_include('inc', 'node', 'node.pages');
$types = node_get_types();
$type = isset($type) ? str_replace('-', '_', $type) : NULL;
// If a node type has been specified, validate its existence.
if (isset($types[$type]) && node_access('create', $type)) {
// Initialize settings:
$node = array('uid' => $user->uid, 'name' => (isset($user->name) ? $user->name : ''), 'type' => $type, 'language' => 'bbb','bbb' => 'TRUE');
$output = drupal_get_form($type .'_node_form', $node);
}
return $output;
}
And here is the hook_form and hook_form_alter code
function author_form_author_node_form_alter(&$form, &$form_state) {
$form['author']=NULL;
$form['taxonomy']=NULL;
$form['options']=NULL;
$form['menu']=NULL;
$form['comment_settings']=NULL;
$form['files']=NULL;
$form['revision_information']=NULL;
$form['attachments']=NULL;
if($form["qqq"]) {
$form['buttons']['preview']=NULL;
}
}
function author_form(&$node) {
return make_author_form(&$node);
}
function make_author_form(&$node) {
global $user;
$type = node_get_types('type', $node);
$node = author_make_title($node);
drupal_set_breadcrumb(array(l(t('Home'), NULL), l(t($node->title), 'node/' . $node->nid)));
$form['authorset'] = array(
'#type' => 'fieldset',
'#title' => t('Author'),
'#weight' => -50,
'#collapsible' => FALSE,
'#collapsed' => FALSE,
);
$form['author_id'] = array(
'#access' => user_access('create pd_recluse entries'),
'#type' => 'hidden',
'#default_value' => $node->author_id,
'#weight' => -20
);
$form['authorset']['last_name'] = array(
'#type' => 'textfield',
'#title' => t('Last Name'),
'#maxlength' => 60,
'#default_value' => $node->last_name
);
$form['authorset']['first_name'] = array(
'#type' => 'textfield',
'#title' => t('First Name'),
'#maxlength' => 60,
'#default_value' => $node->first_name
);
$form['authorset']['middle_name'] = array(
'#type' => 'textfield',
'#title' => t('Middle Name'),
'#maxlength' => 60,
'#default_value' => $node->middle_name
);
$form['authorset']['suffix_name'] = array(
'#type' => 'textfield',
'#title' => t('Suffix Name'),
'#maxlength' => 14,
'#default_value' => $node->suffix_name
);
$form['authorset']['body_filter']['body'] = array(
'#access' => user_access('create pd_recluse entries'),
'#type' => 'textarea',
'#title' => 'Describe Author',
'#default_value' => $node->body,
'#required' => FALSE,
'#weight' => -19
);
$form['status'] = array(
'#type' => 'hidden',
'#default_value' => '1'
);
$form['promote'] = array(
'#type' => 'hidden',
'#default_value' => '1'
);
$form['name'] = array(
'#type' => 'hidden',
'#default_value' => $user->name
);
$form['format'] = array(
'#type' => 'hidden',
'#default_value' => '1'
);
// NOTE in node_example there is some addition code here not needed for this simple node-type
$thepath='milan/author';
if($_REQUEST["theletter"]) {
$thepath .= "/" . $_REQUEST["theletter"];
}
if($node['language']) {
$thepath='milan/authorajaxclose';
$form['qqq'] = array(
'#type' => 'hidden',
'#default_value' => '1'
);
}
$form['#redirect'] = $thepath;
return $form;
}
That menu path coincides with this theme (PHPTemplate)
This might not be it but I see that you use $node as an object at first (title) and then as an array (to get the language) in the make_author_form() method. If $node is an object, then that explains why you cant retrieve $node['language'].
Not sure if I completely understand what you are trying to do but it would be a good idea to use page arguments for it, I think.
function mymodule_form_alter($form_id, &$form) {
// If $form_id is {node->type}_node_form
// Then, check for the first argument in the URL and hide/show Preview accordingly
}
Turned out to be a basic programming error in line 4 of the make_author_form function. I was zeroing out the $node variable myself.