I'm using Drupal 8, and I want to change the markup of more_links from <a href="/node">more</a> to something like <a class="some class" href="/node">more</a>. I have tried with mytheme_preprocess_container(&$vars) with the help of kint debug to analysis the $vars array. $vars['element']['#markup'] returns <a href="/node">more</a>. However, setting it to a value does not applied.

function saidbakr_preprocess_container(&$vars){
 $vars['element']['#markup'] = 'HHHHHHHH';

I tried to use the #children but it has a protected property of markup and I don't know to how use the create method?


What's the problem here?

enter image description here


I just have gotten a semi solution, I regard it semi because it depends on a direct echo from template_preprocess_container like the follwoing:

function saidbakr_preprocess_container(&$vars){
  $elem = $vars['element'];  
  if ($elem['#type'] == 'more_link'){
    $vars['children'] ='';
    echo str_replace('<a','<a class="btn btn-primary" ', $vars['element']['#children']);

I used echo because setting HTML tags string to $vars['children'] leads them to be printed as entities on the page. i.e you see the HTML tag of the link instead of the actual link. Is there any concerns about using direct echo from the preprocess functions?

  • is it a view or a node ?? – Shreya Shetty Aug 9 '16 at 5:16
  • It is a view and the meant markup is printed from variable named {{ more }} in a template named views-view.html.twig. – SaidbakR Aug 9 '16 at 5:20
  • Could you show me the full kint output of the elements ? – Leopathu Aug 9 '16 at 6:06

You should be able to change the more variable in template_preprocess_views_view, like:

function YOUR_THEME_preprocess_views_view(&$variables) {
  $variables['more'] = \Drupal\Core\Render\Markup::create('<a href="#">HHH</a>');
| improve this answer | |
  • Very good, but there is a little problem remaining. I would like to get the markup of the element more i.e <a href="what ever">more</a> in order to apply string replace on it before passing it to the create() method or at least to have the value of what ever for the URL that link points to. – SaidbakR Aug 9 '16 at 16:31
  • so - alter the existing render array markup string, $vars['variables']['#markup'], or extract the href="XX" out of it – rémy Aug 9 '16 at 18:27
  • It's invalid key. However, your solution is the best. It will ultimate one, when we could able to find a way to get the URL or the markup of more link. – SaidbakR Aug 9 '16 at 20:05
  • yes sorry - it's $vars['more']['#markup'] – rémy Aug 9 '16 at 20:54
  • Also it is invalid index. – SaidbakR Aug 9 '16 at 21:04

It's unclear, where you are. The template container has children as output, not element. Also in views-view there is no element. If you change variables, that are not used in the twig, then this will do nothing. Look in the comments at the top of the twig to see what you can change.

But to answer the question. create() is a static function and it is used when you create a new Markup object:

$vars['abc'] = \Drupal\Core\Render\Markup::create('abc');

I don't think Markup has a property or method to change it. You replace the old object with a new one.

| improve this answer | |

As per my understanding you can change the url as well as text of the read more but you will have to implement template_preprocess_links()

Below is code snippet to achieve what you are looking for :

use Drupal\Core\Url;

 function mytheme_preprocess_links(&$variables) {
      // some logic enclosing this block
       $variables['links']['node-readmore']['link']['#title'] = t('Custom text ');
$variables['links']['node-readmore']['link']['#url'] = Url::fromUri('base:' . 'node');
= 'btn btn-primary';

| improve this answer | |
  • This was similar to my answer which I deleted after I realised it's not a read-more link, its a "more" link - i.e. what you get from Views. – Jeff Burnz Aug 9 '16 at 8:00
  • Here I don't meant by node read more. Also, in the case of using preprocess_link how could we restrict the action only on the view more link. – SaidbakR Aug 9 '16 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.