Cross-posting to drupal.stackexchange.com
I am creating a custom field to eventually be displayed in a custom paragraph. I need to upload a JS file for the widget view, but can't seem to get it to work. Can anyone see what I am doing wrong or need to do differently?
I can add the field to the paragraph, add the paragraph to a document and see the fields, but I see no evidence of the JS being attached (the file is not downloaded in the browser and does not activate).
Any help or suggestions are appreciated.
file: src/Plugin/Field/FieldWidget/get_libguides_listings_widget.php:
<?php
namespace Drupal\get_libguides_listings\Plugin\Field\FieldWidget;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Form\FormStateInterface;
class get_libguides_listings_widget extends WidgetBase {
/**
* {#inheritdoc}
*/
public function formElement(
FieldItemListInterface $items,
$delta, array $element, array &$form,
FormStateInterface $form_state) {
$element['Subject_IDs'] = [
'#type'=>'textfield',
'#title'=>$this->t('Subject IDs to Display'),
'#description'=>$this->t('BLAH'),
'#default_value'
=>isset($items->getValue()[$delta]['Subject_IDs'])
?$items->getValue()[$delta]['Subject_IDs']
:'',
'#states'=>[
'visible' => [
[':input[name$="default_value_input[field_libguides_listing][0][SearchBy]"]'
=>['value'=>'subject']],
'or',
[':input[name$="default_value_input[field_libguides_listing][0][SearchBy]"]'
=>['value'=>'both']],
],
],
];
$element['Subject_IDs']['#attached'][]
= 'get_libguides_listings/get_searchby';
return $element;
}
}
file: get_libguides_listings.libraries.yml:
get_searchby:
js:
js/get_searchby.js: {}
dependencies:
- core/jquery
- core/drupal
- core/drupalSettings
file: js/get_searchby.js
/**
* #file
*/
(function(){
alert('hello there');
(function ($, Drupal)
{
Drupal.behaviors.get_searchby = {
attach: function (context, settings)
{
alert('hello');
}
};
}(jQuery, Drupal));
}());
Turns out I forgot the 'library' key $element['Subject_IDs']['#attached']['library'][] = ...
Related
i want to update for exemple contact entity without using form
and i don't know how
this is my code :
/**
* #Route("/UpdateContact/{id}",name="editcontact")
*/
public function EditContact(Contact $Contact , Request $request ,ManagerRegistry $manager)
{
$contact = $this->getDoctrine()
->getRepository(Contact::class)
->findAll();
$request->get('responsable');
$request->get('telephone');
$request->get('email');
$request->get('note');
$contact->setResponsable($request->request->get('responsable'))
->setTelephone ($request->request->get('telephone'))
->setEmail ($request->request->get('email'))
->setNote ($request->request->get('note'));
$manager->persist($contact);
$manager->flush();
return $this->render('companyProfile.html.twig', [
// 'contactform'=>$contactform->createView(),
'Contact' => $contact,
]);
}
it dosen't work so if anyone know how to update without a form , plz help me i'm stuck right now
You need EntityManagerInterface instead of ManagerRegistry
So your code needs to be like this:
<?php
public function EditContact(Contact $contact, Request $request, EntityManagerInterface $em)
{
$contact
->setResponsable($request->get('responsable'))
->setTelephone($request->get('telephone'))
->setEmail($request->get('email'))
->setNote($request->get('note'))
;
$em->persist($contact);
$em->flush();
// rest of your code
}
See https://symfony.com/doc/current/doctrine.html#persisting-objects-to-the-database
I'm having trouble making Sonata Admin Bundle working with Ramsey's Uuid as the entity's Id.
This is the error I get when I try to show the Country list (/admins/app/country/list)
An exception has been thrown during the rendering of a template ("Unknown database type uuid requested, Doctrine\DBAL\Platforms\MySQL57Platform may not support it.").
doctrine.yaml
doctrine:
dbal:
types:
uuid: Ramsey\Uuid\Doctrine\UuidType
services.yaml
sonata.admin.country:
class: App\Admin\CountryAdmin
arguments: [~, App\Entity\Country, ~]
tags:
- { name: sonata.admin, manager_type: orm, group: Entities, label: Country }
App\Entity\Country
class Country
{
/**
* #ORM\Id
* #ORM\Column(type="uuid", unique=true)
* #ORM\GeneratedValue(strategy="CUSTOM")
* #ORM\CustomIdGenerator(class="Ramsey\Uuid\Doctrine\UuidGenerator")
*/
protected $id;
App\Admin\Country
final class CountryAdmin extends Sonata\AdminBundle\Admin\AbstractAdmin
{
protected function configureRoutes(RouteCollection $collection)
{
$collection
->add('show_country', sprintf('%s/show_country', $this->getRouterIdParameter()));
}
}
App\Controller\Admin\CountryController
class CountryController extends Sonata\AdminBundle\Controller\CRUDController
{
public function showCityAction(Request $request): Response
{
/** #var Country $country */
$country = $this->admin->getSubject();
if (!$country) {
$id = $request->get($this->admin->getIdParameter());
throw $this->createNotFoundException(sprintf(
'Unable to find the object with id : %s',
$id
));
}
return $this->renderWithExtraParams('admin/city/show_country.html.twig', [
'show_country' => $country,
]);
}
}
composer.json
"sonata-project/admin-bundle": "^3.53",
"sonata-project/doctrine-orm-admin-bundle": "^3.10",
"sonata-project/translation-bundle": "^2.4",
"sonata-project/user-bundle": "^4.4",
"stof/doctrine-extensions-bundle": "^1.3",
"sonata-project/easy-extends-bundle": "^2.5",
"ramsey/uuid-doctrine": "^1.5"
It seems that the Uuid type is not loaded, although it's in the doctrine.yaml config file. I tried to include it manually in bootstrap.php:
\Doctrine\DBAL\Types\Type::addType('uuid', 'Ramsey\Uuid\Doctrine\UuidType');
but I just get an error message saying the type is already included.
I realised that vendor/sonata-project/doctrine-extensions/src/Types only contains JsonType.php. Could it be that Uuid.php is missing ? Or am I missing something else ? Thank you for your help !
I finally found the answer to this. All I had to do is add the 2 lines to the doctrine.yaml file:
doctrine:
dbal:
types:
uuid: Ramsey\Uuid\Doctrine\UuidType
mapping_types: <---
uuid: uuid <---
I hope it can help someone because personally I couldn't find the information anywhere on the internets !
I need to render a custom form which is created using Drupal\Core\Form\FormBase and Drupal\Core\Form\FormStateInterface through a controller in custom Drupal 8 module. Is there any guidence or reference to follow to do this?
Actually I tried to render form directly and through a controller. But both ways are not working. Only render the submit button. I refer the drupal 8 documentation also. But I couldn't find a solution for this. Please be kind enough to find my coding samples below. If there are anything wrong. Please correct me.
my_module.routing.yml
partner.content:
path: '/partner'
defaults:
_controller: '\Drupal\partner\Controller\PartnerController::add'
_title: 'Add Partner'
requirements:
_permission: 'access content'
partner.addform:
path: '/partner/add'
defaults:
_form: '\Drupal\partner\Form\AddForm'
_title: 'Add Partner'
requirements:
_permission: 'access content'
AddForm.php
namespace Drupal\my_module\Form;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
class AddForm extends FormBase
{
/**
* Returns form id
*
* #return string
*/
public function getFormId(): string
{
return 'my_module_add_form';
}
/**
* Build form array
*
* #param array $form
* #param FormStateInterface $formState
* #return array
*/
public function buildForm(array $form, FormStateInterface $form_state): array
{
// First name
$form['first_name'] = [
'#type' => 'textField',
'#title' => t('First Name'),
'#required' => true,
];
// Other input fields...
$form['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Save Changes'),
'#button_type' => 'primary',
);
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {}
public function submitForm(array &$form, FormStateInterface $form_state) {}
}
MyModuleController.php
<?php
namespace Drupal\my_module\Controller;
use Drupal\Core\Controller\ControllerBase;
use Drupal\my_module\Form\AddForm;
class MyModuleController extends ControllerBase
{
public function add()
{
$addForm = new AddForm();
$form = \Drupal::formBuilder()->getForm($addForm);
return [
'#theme' => 'form_my_module_add',
'#form' => $form,
];
}
}
Happy to find out the solution with Hemantha Dhanushka on my comment.
To make it clear this question has a correct answer, here I past the validated comment.
I would recommend you to use the first approach (using routing::_form instead
of Controller). Also, it seems you use the wrong #type for your
first_name field. Try textfield instead of textField.
Also, for people who want to go further, here are some links to implement a proper
routing::_form approach to expose a form as a page instead of using a Controller: https://www.valuebound.com/resources/blog/step-by-step-method-to-create-a-custom-form-in-drupal-8.
For people looking for more help about existing Form Element Reference (textfield, checkboxes, entity_autocomplete, ...) here is an excellent up-to-date article https://drupalize.me/tutorial/form-element-reference?p=2766
You can use buildForm() method for it. Check below code example:
public function add()
{
$form_state = new Drupal\Core\Form\FormState();
$form_state->setRebuild();
$form = \Drupal::formBuilder()->buildForm('Drupal\my_module\Form\AddForm', $form_state);
return [
'#theme' => 'form_my_module_add',
'#form' => $form,
];
}
Reference: https://api.drupal.org/api/drupal/core!lib!Drupal!Core!Form!FormBuilder.php/function/FormBuilder::getForm/8.2.x
public function install() {
$this->subscribeEvent(
'Enlight_Controller_Action_PostDispatchSecure_Frontend',
'onFrontendPostDispatch',
0
);
return array('success' => true, 'invalidateCache' => array('frontend'));
}
public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
{
/** #var \Enlight_Controller_Action $controller */
$controller = $args->get('subject');
$view = $controller->View();
$view->addTemplateDir(
__DIR__ . '/Views'
);
}
I had tried to run the plugin and override Template but Shopware does not see changes in a plugin.
I am creating new file in /Views/frontend/checkout/cart_footer.tpl in plugins root.
I am also insert
{extends file='parent:frontend/checkout/cart_footer.tpl'}
line in .tpl file but still no success.
Does any one know where is a problem?
This was very easy
I just add one line
$view->loadTemplate('frontend/plugins/checkout/cart.tpl');
And change code little bit.
I am change event from Enlight_Controller_Action_PostDispatchSecure_Frontend to
Enlight_Controller_Action_PostDispatch_Frontend_Checkout
and add $view->loadTemplate('frontend/plugins/checkout/cart.tpl');
This path is related from "/Views" folder which is declared in addTemplateDir method.
Bellow is whole code, Enjoy :)
public function install() {
$this->subscribeEvent(
'Enlight_Controller_Action_PostDispatch_Frontend_Checkout',
'onFrontendPostDispatch'
);
return array('success' => true, 'invalidateCache' => array('frontend'));
}
public function onFrontendPostDispatch(\Enlight_Event_EventArgs $args)
{
/** #var \Enlight_Controller_Action $controller */
$controller = $args->get('subject');
$view = $controller->View();
$view->addTemplateDir(
__DIR__ . '/Views'
);
$view->loadTemplate('frontend/plugins/checkout/cart.tpl');
}
I'm trying to add Fenom Tempate to Yii2 application, but I'm getting a lot of different kinds errors.
I've tried to create a component ViewRenderer and to write code like here, but with my own namespace:
namespace app\components\fenom;
use Yii;
use yii\base\View;
use yii\base\ViewRenderer as BaseViewRenderer;
class ViewRenderer extends BaseViewRenderer {
/**
* #var string the directory, where stores templates.
*/
public $templatePath = '#app/views';
/**
* #var string the directory, where stores compiled templates in PHP files.
*/
public $compilePath = '#runtime/Fenom/compile';
/**
* #var int|array bit-mask or array of Fenom settings.
* #see https://github.com/bzick/fenom/blob/master/docs/en/configuration.md#template-settings
*/
public $options = 0;
/**
* #var \Fenom object that renders templates.
*/
public $fenom;
public function init() {
$this->fenom = \yii\fenom\Fenom::factory($this->templatePath, $this->compilePath, $this->options);
}
public function render($view, $file, $params) {
$params['this'] = $view;
return $this->fenom->fetch($file, $params);
}
}
Added this component to config
'components' => [
'view' => [
'class' => 'yii\web\View',
'renderers' => [
'tpl' => [
'class' => 'app\components\fenom\ViewRenderer',
'options' => [
'auto_reload' => true,
],
],
// ...
],
],
But I'm getting errors. Bad namespace or unwritable directory or another and another errors.
So, my question is: How to add Fenom to Yii2? What and Where should I write (in config, components, or other folders)? What way is the fastest and the most efficient?
Please tell me how to do it properly?
Well, I did it. I'm not sure if this is correct, but...
I made the fenom folder inside the components folder. I put files from the src folder of fenom repo into the /components/fenom.
Also in this folder I created a ViewRenderer.php file. It contains code:
<?php
namespace app\components\fenom;
use Yii;
use yii\base\ViewRenderer as BaseViewRenderer;
class ViewRenderer extends BaseViewRenderer {
/**
* #var string the directory, where stores templates.
*/
public $templatePath = '#app/views';
/**
* #var string the directory, where stores compiled templates in PHP files.
*/
public $compilePath = '#runtime/Fenom/compile';
/**
* #var int|array bit-mask or array of Fenom settings.
* #see https://github.com/bzick/fenom/blob/master/docs/en/configuration.md#template-settings
*/
public $options = ['auto_reload' => true];
/**
* #var \Fenom object that renders templates.
*/
public $fenom;
public function init() {
// put main Fenom class into the yii classmap
Yii::$classMap['Fenom'] = __DIR__.'/Fenom.php';
// call Fenom class autoloader (https://github.com/fenom-template/fenom/blob/master/docs/en/start.md#custom-loader)
\Fenom::registerAutoload(__DIR__."./");
// Yii::getAlias - because it's not understand Yii aliases???
$this->fenom = \Fenom::factory(Yii::getAlias($this->templatePath), Yii::getAlias($this->compilePath), $this->options);
}
public function render($view, $file, $params) {
$params['this'] = $view;
$dirPath = '';
// this is because Fenom do not understand absolute paths???
if (strpos($file, 'views') != false)
$dirPath = explode('views', $file)[1];
if (strpos($file, 'widgets') != false)
$dirPath = explode('widgets', $file)[1];
if (strpos($file, 'modules') != false)
$dirPath = explode('modules', $file)[1];
return $this->fenom->fetch($dirPath, $params);
}
}
I've added ViewRenderer component into the config file:
'components' => [
'view' => [
'class' => 'yii\web\View',
'renderers' => [
'tpl' => [
'class' => 'app\components\fenom\ViewRenderer',
],
],
],
// ...
and created folders inside the runtime folder
- runtime
- Fenom
- compile
- cache
compile - for compiled filed, cache - for cached filed
That's it.
For testing:
/views/site/index.tpl file contains:
{$testtext}
/controllers/SiteController → actionIndex contains:
public function actionIndex() {
return $this->render('index.tpl', ['testtext' => 'It works! Test text']);
}
result:
Something like that...
Installation
Since fenom is an extension on its own, you should use composer to install it. From the docs:
The preferred way to install this extension is through composer.
Either run
php composer.phar require --prefer-dist y2i/yii2-fenom "*"
or add
"y2i/yii2-fenom": "*"
to the require section of your composer.json file.
Usage
The class element in your config file should be a fully qualified class name, not a path to the class file. As such, if installed using composer, you can use the following:
'class' => 'y2i\fenom\ViewRenderer'