how to override $block->content in drupal? - drupal

Now, if i want to override the $block->content which is generated by the Book module... how can I override it and customize the title list? thank you.

You can use the preprocess_block function
function phptemplate_preprocess_block(&$vars) {
if (isset($vars['block'])) {
print_r($vars);
}
}
And dig into those results.
About the content, is this is a module generated block, I hope that $content is renderer using a theme() function, so you just need to alter it.

The $vars argument will have all the information about the blocks being themed. In your case you want the module to be "book".
function phptemplate_preprocess_block(&$vars) {
if (isset($vars['block'])) {
if($vars['block']->module == 'book') {
$vars['block']->content = "My new content";
}
}
}

you can use a preprocess_block function
function yourthemename_preprocess_block(&$vars)
{
if(isset($vars['block']))
{
//i have override a footer_block
if($vars['block']->region == 'footer_block')
{
$vars['content] = "Please Enter Some data";
}
}
}

Related

Determine if block has already been registered

In gutenberg/block-editor, how can I check whether I've already registered a block type? Is there a function I can use? Searching through the Block Editor Handbook I couldn't see a function to check this.
An example of what I am trying to do is below:
class My_Block {
public function __construct() {
if ( ! SOME_FUNCTION_block_exists('foo/column') ) {
register_block_type( 'foo/column', my_args );
}
}
}
In WordPress Gutenberg, using JavaScript you can check if a block exists by name with getBlockType(), eg:
JavaScript
import { getBlockType } from '#wordpress/blocks';
import { registerBlockType } from '#wordpress/blocks';
if (!getBlockType('foo/column')) {
registerBlockType('foo/column', {
edit: Edit,
save,
});
}
While the above is probably the prefered way, there is a valid case for checking in PHP if a block is already registered, eg. if you want to add a render callback for a block with server side rendering. While I haven't seen a core function for this, I've found a way it can be done by using the REST API endpoint for block-types to search for the block by namespace/name:
PHP
class My_Block
{
public function __construct()
{
if (! is_block_registered('foo/column')) {
register_block_type('foo/column', $args);
}
}
private function is_block_registered($block_name)
{
// Use REST API to query if block exists by <namespace>/<name>
$route = new WP_REST_Request('GET', '/wp/v2/block-types/' . $block_name);
$request = rest_do_request($route);
if ($request->status == 404) {
// Block is not found/registered
return false;
}
// Block is registered (status is 200)
return true;
}
}
There is the method ´is_registered()´ in the class ´WP_Block_Type_Registry´ (that class handles the registration of blocks). See the docs: https://developer.wordpress.org/reference/classes/wp_block_type_registry/is_registered/
class My_Block {
public function __construct() {
if ( ! WP_Block_Type_Registry::get_instance()->is_registered( 'foo/column' ) ) {
register_block_type( 'foo/column', my_args );
}
}
}

Hook to change page title

I want to programmatically alter a page title in Drupal 8 so that it will be hard-coded in the theme file.
I'm attempting to use a hook function to preprocess_page_title, but it seems to not understand what page to change the title on.
Here's what I have so far:
function test_preprocess_page_title(&$variables) {
if (arg(0) == 'node/12') {
$variables['title'] = 'New Title';
}
}
I figured the only way to make this change on one specific page is to set the node argument. Has any one figured out a way to override page title on Drupal?
In your template.theme file add the preprocessor and then override page-title.html.twig in your template folder by printing the variable, like below:
function theme_preprocess_page_title(&$variables) {
$node = \Drupal::request()->attributes->get('node');
$nid = $node->id();
if($nid == '14') {
$variables['subtitle'] = 'Subheading';
}
}
then {{ subtitle }}
Here's the method to preprocess your page :
function yourthemename_preprocess_page(&$variables) {
$node = \Drupal::routeMatch()->getParameter('node');
if ($node) {
$variables['title'] = $node->getTitle();
}
}
and in your template page.html.twig
{{title}}
There are a couple of solutions to change the page title
On template
/**
* Implements hook_preprocess_HOOK().
*/
function MYMODULE_preprocess_page_title(&$variables) {
if ($YOUR_LOGIC == TRUE) {
$variables['title'] = 'New Title';
}
}
On the node view page
/**
* Implements hook_ENTITY_TYPE_view_alter().
*/
function mymodule_user_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
if ($YOUR_LOGIC == TRUE) {
$build['#title'] = $entity->get('field_display_name')->getString();
}
}
for a sample if you want to change user title
function mymodule_user_view_alter(array &$build, Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display) {
if ($entity->getEntityTypeId() == 'user') {
$build['#title'] = $entity->get('field_first_name')->getString();
}
}
On Controller or hook_form_alter
if ($YOUR_LOGIC == TRUE) {
$request = \Drupal::request();
if ($route = $request->attributes->get(\Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT)) {
$route->setDefault('_title', 'New Title');
}
}
The Page Title is a block in Drupal 8. If you can find the plugin_id of the page title block (which is likely to be page_title_block), then you can override the title directly, with no need to change an existing twig template, using a block preprocessor. Your code may be similar to the following:
function vhs_preprocess_block(&$variables) {
// This example restricts based on the actual URL; you can replace this with any other logic you wish.
$request = \Drupal::request();
$uri = $request->getRequestUri();
if (
isset($variables['elements']['#base_plugin_id']) &&
$variables['elements']['#base_plugin_id'] == 'page_title_block' &&
isset($variables['content']['#title']['#markup']) &&
strpos($uri, '/url-to-match') === 0 // replace with logic that finds the correct page to override
) {
$variables['content']['#title']['#markup'] = 'My Custom Title';
}
}
The example above uses the Drupal request object to grab and compare the actual URL. The initial question asked to match based on the node path; you could get that with something like:
$current_path = \Drupal::service('path.current')->getPath();
Then, in place of the strpos condition above, you could use:
$current_path == 'node/12'
i have changed the page_title block for user/uid to a different custom account field name like this :
function hook_preprocess_block(&$variables) {
$path = \Drupal::request()->getpathInfo();
$arg = explode('/', $path);
if (isset($arg[2]) && $arg[2] == 'user' && isset($arg[3])) {
if (isset($variables['elements']['content']['#type']) && $variables['elements']['content']['#type'] == 'page_title') {
$account = \Drupal\user\Entity\User::load($arg[3]);
if(isset($account) && isset($account->field_mycustomfield->value)){
$variables['content']['#title']['#markup']=$account->field_mycustomfield->value;
}
}
}
}

How to access global telerik functions in typescript

I try to access the function GetRadWindowManager() from my app.ts file.
I added the definitions files and I cannot find a way to call "window.GetRadWindowManager()" or "window.top.GetRadWindowManager()"
That is my code until now :
export class App {
private _windowManager: Telerik.Web.UI.RadWindowManager;
constructor() {
this._windowManager = null;
}
getRadWindowManager(): Telerik.Web.UI.RadWindowManager {
if (this._windowManager == null) {
try {
this._windowManager = window.top.GetRadWindowManager();
} catch (err) {
this._windowManager = GetRadWindowManager();
}
}
return this._windowManager;
}
}
PS : Don't mind the try/catch block, I'll remove that later :)
Thanks for your help !
Well, I don't know if this answer is the best, but extending the Window object allowed me to manually add this function. Then I can simply call it from my script.ts
interface Window {
GetRadWindowManager(): Telerik.Web.UI.RadWindowManager;
}

SilverStripe Inheriting elements from a parent dataobject

I have set a field called Colour in Page.php and for any child I would like to grab the parent colour or loop through till it finds a parent that does have the colour field set.
I have a function below which seems to work in 2.4 but I cannot get to work in SS3 which I call inside a loop in templates as $Inherited(Colour).
Your help is appreciated
public function Inherited($objName) {
$page = $this->owner->Data();
do {
if ($obj = $page->obj($objName)) {
if ($obj instanceof ComponentSet) {
if ($obj->Count()) {
return $obj;
}
} elseif ($obj instanceof DataObject) {
if ($obj->exists()) {
return $obj;
}
} elseif ($obj->exists()) {
return $obj;
}
}
} while ($page->ParentID != 0 && $page = $page->Parent());
}
Assuming your Colour field is a database field and not a relationship to another data object, add the following method to your Page class.
public function getColour() {
// Try returning banners for this page
$colour = $this->getField('Colour');
if ( $colour ) {
return $colour;
}
// No colour for this page? Loop through the parents.
$parent = $this->Parent();
if ( $parent->ID ) {
return $parent->getColour();
}
// Still need a fallback position (handled by template)
return null;
}
If colour is a related data object you could do much the same thing but use the getComponent or getComponents method in place of getField in the code above. This should work on both Silverstripe version 2.4.x and 3.0.x.
This kind of operation, although useful, should probably be done sparingly or be heavily cached as it's recursive could conceivably happen on the majority of page loads, and change very infrequently.
i suppose you've had this function defined inside some DataObjectDecorator, as you're using $this->owner to refer to the current page.
there is no more DataObjectDecorator in SilverStripe 3 (see http://www.robertclarkson.net/2012/06/dataextension-class-replacing-dataobjectdecorator-silverstripe-3-0/) so there are two possible solutions:
a) replace DataObjectDecorator by DataExtension
b) simply move the Inherited function to your Page class, and replace $this->owner by $this

how to set default option of node reference cck field through form alter

I accept the arg from the url and according to the arg value I need to set the default option value, here is the code:
function ims_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'media_content_node_form':
unset($form['buttons']['preview']);
$form['#redirect'] = 'mediacontent';
if(is_numeric(arg(3)))
{
$arg_nid = arg(3);
foreach($form['field_media_model']['#options'] as $k=>$v)
{
if($v==$arg_nid)
{
$form['field_media_model']['#default_value'] = $v;
}
}
}
break;
}
}
First you should steer away from a switch construction if you are only testing one thing; use an if.
Second, as per your own comment, you were using the variables wrong.
And third, why all the extra cruft, such as unsetting values, looping trough #options, and redirecting?
function ims_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'media_content_node_form') {
$nid = arg(3);
if(($nid = arg(3)) && is_int($nid)) {
$form['field_media_model']['#default_value'][0]['nid'] = $nid;
}
}
}
i was accessing the value of element wrongly, because it's a node reference field the right way to access that element is $form['field_media_model']['#default_value'][0]['nid']

Resources