We can create a view from admin panel. But I want to create a view using php code. Can anyone show me the way?
There is code floating around that wouldn't work for me. But This one did. Add this php to your .module file. Then create a views folder and then put all your views in there with the extension of .inc. Each view file will simply be <?php followed by the exact export of the view...
/**
* Implements hook_views_api().
*/
function MODULENAME_views_api() {
return array ('api' => 3.0);
}
function MODULENAME_views_default_views() {
// Check for all view file in views directory
$files = file_scan_directory(drupal_get_path('module', 'MODULENAME') . '/views', '/.*\.inc$/');
// Add view to list of views
foreach ($files as $filepath => $file) {
require $filepath;
if (isset($view)) {
$views[$view->name] = $view;
}
}
// At the end, return array of default views.
return $views;
}
Related
Is posible to save SS template variable in database from CMS and after execute it in template?
Okay lets see example:
In CMS i have settings where i put social media links and contact informatios.
Also in CMS i have module where i create HTML block-s which after that i loop in website.
In that html block i want to put existing $SiteConfig.Email variable.
I Try that but that is rendered in template like $SiteConfig.Email not show real email?
Is this posible to do or i need some extra modification?
Check photo
The question you have written makes no sense to me, but I understand the screenshot.
So, SilverStripe renders .ss files with a class called SSViewer. Basically it reads the file as string and then runs it through SSViewer to generate the HTML output.
But, as you saw, the output of variables is not processed.
I can think of 3 ways to get what you want:
Run the variables through SSViewer aswell (in this example, use $RenderedHTMLContent in the template)
class MyDataObject extends DataObject {
private static array $db = [
'Title' => DBVarchar::class,
'HTMLContent' => DBText::class,
];
public function Foobar() { return "hello from foobar"; }
public function RenderedHTMLContent() {
$template = \SilverStripe\View\SSViewer::fromString($this->HTMLContent);
// using $this->renderWith() will allow you access to all things of $this in the template. so eg $ID, $Title or $Foobar. Probably also $SiteConfig because it's global
return $this->renderWith($template);
// if you want to add extra variables that are not part of $this, you can also do:
return $this->renderWith($template, ["ExtraVariable" => "Hello from extra variable"]);
// if you do not want $this, you can do:
return (new ArrayData(["MyVariable" => "my value"]))->renderWith($template);
}
}
Please be aware of the security implications this thing brings. SilverStripe is purposely built to not allow content authors to write template files. A content author can not only call the currently scoped object but also all global template variables. This includes $SiteConfig, $List, .... Therefore a "bad" content author can write a template like <% loop $List('SilverStripe\Security\Member') %>$ID $FirstName $LastName $Email $Salt $Password<% end_loop %> or perhaps might access methods that have file access. So only do this if you trust your content authors
Use shortcodes instead of variables. But I never liked shortcodes, so I don't remember how they work. You'll have to lookup the docs for that.
Build your own mini template system with str_replace.
class MyDataObject extends DataObject {
private static array $db = [
'Title' => DBVarchar::class,
'HTMLContent' => DBText::class,
];
public function Foobar() { return "hello from foobar"; }
public function RenderedHTMLContent() {
return str_replace(
[
'$SiteConfig.Title',
'$SiteConfig.Tagline',
'$Title',
'$Foobar',
],
[
SiteConfig::current_site_config()->Title,
SiteConfig::current_site_config()->Tagline,
$this->Title,
$this->Foobar(),
],
$this->HTMLContent
);
}
}
I want build a form using a block module in Drupal 8. I am aware of building the forms in Drupal 7 but the same seems to be different in Drupal 8.
Request anyone who has worked on drupal8 custom forms as block to help me.
Your question is very vague, as I don't know how much you already know about modules, forms and blocks in Drupal 8. So here is a small guide what to do, further information on how to do stuff in detail would be overkill for this answer.
1. Create a new module and enable it
Look here: Naming and placing your Drupal 8 module.
Basically you create the module folder and the module info yml file to let Drupal know about the module. Then you enable it using drush or the admin area in Drupal.
2. Create the form
Look here: Introduction to Form API.
under your_module/src/Form you create the form. More details in the link above.
3. Create the block and render the form
Look here: Create a custom block.
under your_module/src/Plugin/Block/ you create the block which will render the form.
The idea is basically (code updated with suggestion from Henrik):
$builtForm = \Drupal::formBuilder()->getForm('Drupal\your_module\Form\YourForm');
$renderArray['form'] = $builtForm;
return $renderArray;
Note: You don't need to wrap the $builtForm with the $renderArray, you can return just the $builtForm and be fine. I just personally like to do it that way, because often times I need to add something else to the final render array like some markup, cache settings or a library etc.
4. Place the block
Place the block in the desired region(s). Done.
To build a form using block module, you can easily use Webform module where you can add a form and display as a block.
If you mean to create a form programatically in the custom block, you can achieve that by creating two files shown below:
Form file (src/Form/DemoForm.php):
<?php
/**
* #file
* Contains \Drupal\demo\Form\DemoForm.
*/
namespace Drupal\demo\Form;
use Drupal\Core\Form\FormBase;
class DemoForm extends FormBase {
/**
* {#inheritdoc}.
*/
public function getFormId() {
return 'demo_form';
}
/**
* {#inheritdoc}.
*/
public function buildForm(array $form, array &$form_state) {
$form['email'] = array(
'#type' => 'email',
'#title' => $this->t('Your .com email address.')
);
$form['show'] = array(
'#type' => 'submit',
'#value' => $this->t('Submit'),
);
return $form;
}
/**
* {#inheritdoc}
*/
public function validateForm(array &$form, array &$form_state) {
$values = $form_state->getValues();
if (strpos($values['email'], '.com') === FALSE ) {
$form_state->setErrorByName('email', t('This is not a .com email address.'));
}
}
/**
* {#inheritdoc}
*/
public function submitForm(array &$form, array &$form_state) {
drupal_set_message($this->t('Your email address is #email', array('#email' => $form_state['values']['email'])));
}
}
Source: Building a Drupal 8 Module: Blocks and Forms.
Block file (src/Plugin/Block/HelloBlock.php):
<?php
namespace Drupal\mymodule\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a 'Hello' Block.
*
* #Block(
* id = "form_block",
* admin_label = #Translation("My form"),
* category = #Translation("My Category"),
* )
*/
class HelloBlock extends BlockBase {
/**
* {#inheritdoc}
*/
public function build() {
$form = \Drupal::formBuilder()->getForm('\Drupal\mymodule\Form\HelloBlock');
//$form['#attached']['js'][] = drupal_get_path('module', 'example') . '/js/example.js';
//$form['#markup'] = $this->t('Custom text');
return $form;
}
}
Source: Create a custom block.
To add a form to the Block Configuration, see: Add a Form to the Block Configuration.
Here is a detailed summary of how to go about this:-
https://www.sitepoint.com/building-drupal-8-module-blocks-forms/
Following the above guide, you would add the completed form to the block build function, e.g.
class DemoBlock extends BlockBase {
/**
* {#inheritdoc}
*/
public function build() {
$form = \Drupal::formBuilder()->getForm('Drupal\demo\Form\DemoForm');
return $form;
}
}
Some more useful docs if you are new to Drupal 8 or need to dust off your knowledge:
https://www.drupal.org/docs/8/creating-custom-modules
https://www.drupal.org/docs/8/api/block-api
https://www.drupal.org/docs/8/api/form-api
I would like to add new button to order's list view, but I have no idea how to do it:
I want to do it in way that new upgrade will not delete it.
Edit: This new button will just open new browser window so it's completely independent of PrestaShop functionalities. But I would like to put it in this toolbar line.
Thank you for your help!
You could do it with overrides. Create a file called AdminOrdersController.php in your overrides/controllers/admin/ folder, and add the following:
<?php
class AdminOrdersController extends AdminOrdersControllerCore
{
public function initPageHeaderToolbar()
{
parent::initPageHeaderToolbar(); // this will assign native icons
// This is where you add you custom icon
$this->page_header_toolbar_btn['my_custom_icon'] = array(
'href' => self::$currentIndex.'&mycustomaction&token='.$this->token,
'desc' => $this->l('My custom action', null, null, false),
'icon' => 'process-icon-save'
);
}
public function initProcess()
{
parent::initProcess();
if (Tools::getIsset('mycustomaction')) {
if ($this->tabAccess['view'] === '1') {
$this->display = 'mycustomaction';
$this->action = 'mycustomaction';
}
else
$this->errors[] = Tools::displayError('You do not have permission to edit this.');
}
}
public function initContent()
{
parent::initContent();
if ($this->display == 'mycustomaction')
$this->content.= $this->renderMyCustomAction();
}
public function renderMyCustomAction()
{
// this is where you render your custom page.
}
}
Note that this is a quick mock up. It should work, though :)
UPDATE
If you just want the icon to open a new page, leave only the initPageHeaderToolbar method and provide the right href attribute, you can delete the initProcess, initContent and renderMyCustomAction methods. I'll leave them in my original reply in case someone else finds it useful.
I have correctly created a custom widget, evreything is translating well with a correct .po file, except the title.
Here is my code :
$concert_widget_name = __('Tour Dates', 'concerts');
wp_register_sidebar_widget (
'tourdates', // your unique widget id
$concert_widget_name, // widget name
'tourdates_widget_display', // callback function to display widget
array( // options
'description' => 'Displaying upcoming tour dates'
)
);
Is there an error ? An other way to translate the widget name ?
I usually register my widgets using the register_widget function. In the constructor of the widget class I place the following code:
class TourDates extends WP_Widget
{
public function __construct()
{
$options = array('classname' => 'tour-dates', 'description' => __('Display upcoming tour dates'));
parent::__construct('tour_dates', __('Tour Dates'), $options);
}
}
You can also check out the Widgets API on the WordPress Codex site. Hopefully this helps you in creating your custom widget.
Also what I usually do is merge my translations with the default ones loaded from WordPress, like so:
function loadTextDomain() {
$locale = get_locale();
$languageDir = dirname(__FILE__) . '/languages';
$domain = 'default';
$mofile = $languageDir . '/theme.' . $locale . '.mo';
global $l10n;
$mo = new MO();
if (!$mo->import_from_file($mofile)) {
return false;
}
if (isset($l10n[$domain]) && !empty($l10n[$domain]->entries)) {
$l10n[$domain]->merge_with($mo);
} else {
$l10n[$domain] = $mo;
}
}
add_action('init', 'loadTextDomain');
This code looks similar to the load_textdomain function from WordPress but it avoids all the filters that do exist in the original function, which helps in avoiding any WordPress hook from altering your $domain and $mofile variables.
But I will leave that up to you. Maybe the load_textdomain() function from WordPress will work just as fine, but in case it doesn't this function should do the trick.
Now if your using the loadTextDomain() function I pasted above you can just place a languages folder in the same folder as your functions.php resides, in that new folder you could place theme.nl_NL.mo or theme.de_DE.mo files depending on the language your using. This should allow translation of your website and also the admin area.
How can I switch to a different theme template file for any node that I want?
I understand how to create sub-themes like node-recipes.tpl.php for a node that has a path of "recipes". But what I want to have control of the entire base template like page.tpl.php.
Can I use some preprocess function in template.php for this?
Right now I have this in my template.php file:
function mythemename_preprocess_node(&$vars) {
// template name for current node id
$suggestions = array('node-'. $vars['nid']);
// additional node template names based on path alias
if (module_exists('path')) {
// we already can have a path alias
if (isset($vars['path'])) {
$alias = $vars['path'];
}else{
// otherwise do standard check
$alias = drupal_get_path_alias('node/'. $vars['nid']);
}
if ($alias != 'node/'. $vars['nid']) {
$add_path = '';
foreach (explode('/', $alias) as $path_part) {
$add_path .= !empty($path_part) ? $path_part.'_' : '';
$suggestions[] = 'node-'. $add_path;
}
// adding the last one (higher priority) for this path only
// node-some-long-path-nofollow.tpl.php (not for anchestors)
$suggestions[] = end($suggestions) .'-nofollow';
}
$suggestions=array_map(stripTag, $suggestions);
//print_r($suggestions);
}
$vars['template_files'] = isset($vars['template_files']) ? array_merge($vars['template_files'], $suggestions) : $suggestions;
}
thanks
Yes,
You can fully control the $vars['template_files'] array. I always suggest adding onto the array rather then overwriting it completely.
I have a module that I maintain that adds a few small suggestions that I use often.
http://github.com/electblake/template_suggestions/blob/master/template_suggestions.module
You can manipulate the $vars['template_files'] array in preprocess_node, preprocess_page, etc.
If you want to switch you page.tpl.php to another theme file do it in the preprocess_page hook...
I'm using this function to create template suggestions that works for me now. Thanks for the suggestions everyone.
/**
* Override or insert PHPTemplate variables into the templates.
* These are the main outer templates such as page.tpl.php
*/
function phptemplate_preprocess_page(&$vars) {
$alias = drupal_get_path_alias($_GET['q']);
if ($alias != $_GET['q']) {
$template_filename = 'page';
foreach (explode('/', $alias) as $path_part) {
$template_filename = $template_filename . '-' . $path_part;
$vars['template_files'][] = $template_filename;
}
}
//----
//print_r(arg());
/* print '<pre>';
print_r($vars);
print '</pre>';*/
//dpm($vars);
//print_r($vars['template_files']);
}