Augmented Reality – Is it possible to recognize a QR code in a rendered 3D object in AR?

My idea here is that when a user arrives at a GPS location in the game, an AR view recognizes the environment and displays a rendered 3D game object.

But I also want this virtual 3D game object to contain a random QR / Pin code that the app can then recognize and read. Trigger other navigation.

Kind of like the beginning.

ajax – I want to add a pagination below the rendered twig table to update the rendered twig table and pagination forms for the next and previous buttons

What I have:

I want to use an external API and display the results on the page.

  1. To that end, I created a custom route that is attached to the controller with a custom twig design.
  2. When you visit this route, load the function in the controller onto the external API, call up the data and pass this data in array form to the custom Twig template.
  3. Since the external API also offers a search function, we created a form and added this form with the Drupal form generator and also sent this form over the data in the array. With Twig this search form is attached to and above the search results table.
  4. Now I want to add a pagination under the Twig results table with the buttons for the next page and the previous page. The pagination functionality is provided by the API itself, and the links to the new and previous page are given in the API response itself. With Ajax callback, I'm trying to update my data and resend to the Twig template, but it doesn't work.

What I created for pagination:

  1. The Controller Form Builder creates a new form without a route and adds it to the Twig template.
  2. I pass the URL of the next page and the URL of the previous page as parameters to the form.
  3. This parameter is used in the build form function.
  4. I appended the URL of the next and previous page with custom arguments to the form elements.

Now when you click the next button, the new data is loaded via an Ajax call attached to the button for the next page in the form, and the twig table is updated with data for page 2. When the next button is clicked again, the same URL is called again even after the field arguments in the Ajax callback have been updated.

If my approach is wrong, please let me know that I am ready to correct my approach.

MyController.php


/**
 * @file
 * Contains Drupaldtn_feedControllerAPFeedListController.
 */

namespace Drupaldtn_feedController;

use DrupalCoreControllerControllerBase;
use DrupalComponentSerializationJson;
use DrupalCoreLoggerLoggerChannelFactory;
use DrupalCoreMessengerMessengerInterface;
use Drupaldtn_feedSearchAndFeedHandler;
use SymfonyComponentDependencyInjectionContainerInterface;

/**
 * Returns responses for Quick Node Clone Node routes.
 */
class APFeedListController extends ControllerBase {

  /**
   * @var searchFeedHandler
   *   Variable used for loading search feed handler service.
   */
  protected $searchFeedHandler;

  /**
   * @var url
   *   Variable used to store $url.
   */
  protected $url;

  /**
   * @var next_page_url
   *  Variable used to hold next page url
   */
  protected $next_page_url;

  /**
   * @var previous_page_url
   *  Variable used to hold previous page url
   */
  protected $previous_page_url;

  /**
   * Constructs a NodeController object.
   *
   * @param DrupalCoreLoggerLoggerChannelFactory $logger_factory
   *   Passing an Instance of logger factory.
   * @param DrupalCoreMessengerMessengerInterface $messenger
   *   The messenger service.
   * @param Drupaldtn_feedSearchAndFeedHandler $search_feed_handler
   *   The search feed handler custom service.
   */
  public function __construct(LoggerChannelFactory $logger_factory, MessengerInterface $messenger, SearchAndFeedHandler $search_feed_handler)
  {
    $this->loggerFactory = $logger_factory;
    $this->messenger = $messenger;
    $this->searchFeedHandler = $search_feed_handler;
  }
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container)
  {
      return new static(
      $container->get('logger.factory'),
      $container->get('messenger'),
      $container->get('dtn_feed.feed.feed_api_handler')
    );
  }
  /**
   * Create Feed Url.
   *
   * @return string
   */
  private function getFeedUrl() {
    $urlParams = 'search?q=';
    $url = $this->searchFeedHandler->generateUrl($urlParams);
    return $url;
  }
  /**
   * Lists Feeds.
   *
   * @return array
   */

  public function listFeeds() {
    $url = $this->getFeedUrl();
    $jsonFeedData = $this->searchFeedHandler->getApFeeds($url);
    $decodedJsonFeedData = Json::decode($jsonFeedData);
    $searchForm = $this->formBuilder()->getForm('Drupaldtn_feedFormApFeedsSearchForm');

    if (isset($decodedJsonFeedData('data')('next_page'))) {
      $items('next_page') = $decodedJsonFeedData('data')('next_page');
      $this->next_page_url = $decodedJsonFeedData('data')('next_page');
    }

    $items('current_page') = $decodedJsonFeedData('data')('current_page');

    if (isset($decodedJsonFeedData('data')('previous_page'))) {
      $items('previous_page') = $decodedJsonFeedData('data')('previous_page');
      $this->previous_page_url = $decodedJsonFeedData('data')('previous_page');
    }

    $paginationForm = $this->formBuilder()->getForm('Drupaldtn_feedFormApFeedsPaginationForm', $items);

    return (
      '#theme' => 'dtn_feed_apFeeds_list',
      '#search_form' => $searchForm,
      '#feedsList' => $decodedJsonFeedData,
      '#pagination_form' => $paginationForm,
    );
  }

 /**
  * Reads the data from the json file.
  *
  * @return array
  *   jsonData
  */
  public function readJsonData() {
    $currentDirectory = drupal_get_path('module', 'dtn_feed');
    $path = $currentDirectory . '/ApJsonData/ApData.json';
    $data = file_get_contents($path);
    return $data;
  }

}

My form.php


namespace Drupaldtn_feedForm;

use DrupalComponentSerializationJson;
use DrupalCoreFormFormBase;
use DrupalCoreFormFormStateInterface;
use Drupaldtn_feedSearchAndFeedHandler;
use SymfonyComponentDependencyInjectionContainerInterface;
use DrupalCoreConfigConfigFactoryInterface;
use DrupalCoreFormFormBuilderInterface;
use DrupalCoreAjaxAjaxResponse;
use DrupalCoreAjaxReplaceCommand;
/**
 * Provide a search form for search AP Feed.
 */
class ApFeedsPaginationForm extends FormBase {

  /**
   * @var SearchAndFeedHandler $feed_api_handler
   */
  protected $feed_api_handler;

  /**
   * @var configFactoryInterface
   */
  protected $config_factory;

  /**
   * @var FormBuilderInterface
   */
  protected $form_builder;


  /**
   * Class constructor.
   * @param SearchAndFeedHandler $feed_api_handler
   */

  public function __construct(SearchAndFeedHandler $feed_api_handler, ConfigFactoryInterface $configFactory, FormBuilderInterface $formBuilder)
  {
    $this->feed_api_handler = $feed_api_handler;
    $this->config_factory = $configFactory;
    $this->form_builder = $formBuilder;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container)
  {
    return new static(
      $container->get('dtn_feed.feed.feed_api_handler'),
      $container->get('config.factory'),
      $container->get('form_builder')
    );
  }

  /**
   * {{ @inheritDoc }}
   */
  public function getFormId()
  {
    return 'dtn_feed_ap_feed_pagination_form';
  }

  /**
   * {{ @inheritDoc }}
   */
  public function buildForm(array $form, FormStateInterface $form_state, $items = ()) {
    $form('#theme') = 'dtn_feed_pagination_form';
    $form('pagination') = (
      '#type' => 'fieldset',
      '#title' => $items('next_page'),
      '#open' => TRUE,
    );
    $form('pagination')('previous') = (
      '#type' => 'button',
      '#value' => t('Previous'),
      '#attributes' => (
        'disabled' => 'disabled'
      ),
    );
    $form('pagination')('next') = (
      '#type' => 'button',
      '#value' => $this->t("Next"),
      '#attributes' => (
        '#args' => $items('next_page'),
        // 'disabled' => 'disabled'
        // 'id' => "next-page"
      ),
      '#ajax' => (
        'callback' => '::getApNewsSearchResult',
        'event' => 'click',
        'wrapper' => 'ap-news-table-list',
        'progress' => (
          'type' => 'throbber',
          'message' => $this->t('Getting news for you...'),
        ),
      ),
    );

    return $form;
  }

  /**
   * {{ @inheritDoc }}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $form_state->setRebuild(TRUE);

    $form_state->setCached(FALSE);
    // @todo Needs to decide what is to be done upon form submission.
  }

  /**
   * Get Search result from Ap News.
   * @param array $form
   * @param FormStateInterface $form_state
   * @return mixed
   */
  public function getApNewsSearchResult(array &$form, FormStateInterface &$form_state) {
    $config = $this->config_factory->getEditable('dtn_feed.ap_feed_conf');

    $api_key = $config->get('ap_feed_key');

    $url = $form('pagination')('next')('#attributes')('#args') . '&apikey=' . $api_key;

    $resultJson = $this->feed_api_handler->getJsonBodyFromAp($url);

    $decodedJsonData = JSON::decode($resultJson);

    if (isset($decodedJsonData('data')('next_page'))) {
      $items('next_page') = $decodedJsonData('data')('next_page');
    }

    $items('current_page') = $decodedJsonData('data')('current_page');

    if (isset($decodedJsonData('data')('previous_page'))) {
      $items('previous_page') = $decodedJsonData('data')('previous_page');
    };

    $form('pagination')('next')('#attributes')('#args') = $items('next_page');
    $url = $form('pagination')('next')('#attributes')('#args');
    $form('pagination')('#title') = $url;

    return (
      "#theme" => 'dtn_feed_apFeeds_list',
      "#feedsList" => $decodedJsonData,
      '#pagination_form' => $form,
    );
  }

}

Theming – How do I change the view of a rendered product?

I am learning Drupal Commerce with a Commerce Kickstart installation. I partially understood how products are displayed, with variation types and content types.

Have you made some changes, e.g. B. visible / hidden product fields and change the order. Product fields are displayed.

I want to change the position of the image on the left and title, description and Add to Cart Button should stay on the right.

How can I do that?

Enter the image description here

magento2.3.3 – The comment block for Magento 2.3 orders is not rendered correctly

I am working on the Marketplace extension, which does not provide an order comment block. So I'm going to adjust this.

At the moment the comment history block is displayed properly. A comment with a notified email has also been added to the order.

After submitting a comment, the block should be rendered with the latest comment, but not in my case.

A black Magento page is displayed.

The following code has been added.

getSubmitUrl() . "')";
        $button = $this->getLayout()->createBlock(
            MagentoBackendBlockWidgetButton::class
        )->setData(
            ('label' => __('Submit '), 'class' => 'action-save action-secondary', 'onclick' => $onclick)
        );
        $this->setChild('submit_button', $button);
        //return parent::_prepareLayout();
        return $this;
    }
}

order_history_block This is the HTML div element ID that is present in .phtml

Check boxes are not rendered in the form after the update to Drupal Core 8.8.0. Is there a warning for the count () function?

We have adapted the Exact Target (Marketing Cloud) module. The newsletter form with check boxes to choose from is not displayed.
After the update to Drupal Core 8.8.0 and PHP 7.2 the check boxes are not rendered and throw errors.

Failed to get lists.
Warning: count (): The parameter must be an array or an object, the countable in Drupal Core Render Element Checkboxes :: processCheckboxes () (line 58 of core / lib / Drupal / Core / Render / Element / Checkboxes ) implemented. php).
Drupal Core Render Element Checkboxes :: processCheckboxes (array, object, array)
call_user_func_array (Array, Array) (line: 999)
Drupal Core Form FormBuilder-> doBuildForm (& # 39; exact_target_Newsletter_ajax_form & # 39 ;, array, object) (line: 1062)
Drupal Core Form FormBuilder-> doBuildForm (& # 39; exact_target_Newsletter_ajax_form & # 39 ;, array, object) (line: 563)
Drupal Core Form FormBuilder-> processForm (& # 39; exact_target_Newsletter_ajax_form & # 39 ;, array, object) (line: 320)
Drupal Core Form FormBuilder-> buildForm (& # 39; Drupal exact target Form NewsLetterAjaxForm & # 39 ;, object) (line: 218)
Drupal Core Form FormBuilder-> getForm (& # 39; Drupal exact target Form NewsLetterAjaxForm & # 39;) (line: 30)
getSubscriptionForm () (line: 19)
exact_target_preprocess_page (array, & # 39; page & # 39 ;, array) (line: 287)
Drupal Core Theme ThemeManager-> render (& # 39; Page & # 39 ;, Array) (line: 431)
Drupal Core Render Renderer-> doRender (Array,) (line: 200)
Drupal Core Render Renderer-> Rendering (Array) (line: 501)
Drupal Core Template TwigExtension-> EscapeFilter (object, array, & # 39; html & # 39 ;, NULL, 1) (line: 103)
__TwigTemplate_4d0e70ebfbbb3174bc5f8489ec870a7b46da766d7ad6ab3338dcce8396067f59-> doDisplay (Array, Array) (line: 455)
Twig Template-> displayWithErrorHandling (Array, Array) (line: 422)
Branch Template-> Display (Array) (line: 434)
Branch Template-> Render (Array) (line: 64)
twig_render_template (& # 39; theme / custom / bootstrap_tsnn / templates / html.html.twig & # 39 ;, array) (line: 384)
Drupal Core Theme ThemeManager-> render (& # 39; html & # 39 ;, array) (line: 431)
Drupal Core Render Renderer-> doRender (Array,) (line: 200)
Drupal Core Render Renderer-> Rendering (Array) (line: 147)
Drupal Core Render MainContent HtmlRenderer-> Drupal Core Render MainContent {closure} () (line: 573)
Drupal Core Render Renderer-> executeInRenderContext (object, object) (line: 148)
Drupal Core Render MainContent HtmlRenderer-> renderResponse (array, object, object) (line: 90)
Drupal Core EventSubscriber MainContentViewSubscriber-> onViewRenderArray (object, & # 39; kernel.view & # 39 ;, object)
call_user_func (array, object, & # 39; kernel.view & # 39 ;, object) (line: 111)
Drupal Component EventDispatcher ContainerAwareEventDispatcher-> dispatch (& # 39; kernel.view & # 39 ;, Object) (line: 156)
Symfony Component HttpKernel HttpKernel-> handleRaw (object, 1) (line: 68)
Symfony Component HttpKernel HttpKernel-> handle (Object, 1, 1) (line: 57)
Drupal Core StackMiddleware Session-> Handle (object, 1, 1) (line: 47)
Drupal Core StackMiddleware KernelPreHandle-> handle (Object, 1, 1) (line: 191)
Drupal page_cache StackMiddleware PageCache-> fetch (Object, 1, 1) (line: 128)
Drupal page_cache StackMiddleware PageCache-> Lookup (object, 1, 1) (line: 82)
Drupal page_cache StackMiddleware PageCache-> handle (Object, 1, 1) (line: 50)
Drupal ban BanMiddleware-> handle (Object, 1, 1) (line: 59)
Drupal httpbl HttpblMiddleware-> handle (Object, 1, 1) (line: 47)
Drupal Core StackMiddleware ReverseProxyMiddleware-> handle (Object, 1, 1) (line: 52)
Drupal Core StackMiddleware NegotiationMiddleware-> handle (Object, 1, 1) (line: 23)
Stack StackedHttpKernel-> handle (Object, 1, 1) (line: 694)
Drupal Core DrupalKernel-> handle (object) (line: 19)

Python – Can a Django template be immediately streamed to the client in blocks without waiting for it to be fully rendered?

I remember working with PHP a long time ago and a website was streamed directly to the client. If a PHP block was found, the stream was blocked until the string was returned by PHP, and then data continued to be sent to the client. If an exception was found, part of the website and then the exception could be displayed in the middle of the website.

I want to be able to send a Django template to the client in the same way as PHP. For example:

1. 
2.   
3.     ...
4.   
5.   
6.     hello {{ some_context_variable }} bye
7.   
8. 

If some_context_variable is a long database operation that the user should see hello in the browser, until a few seconds pass and the database operation is solved, the user would see something like on the screen hello friend bye

Can this be done with Django views and rendering a Django template? If not, could this be done with another template language like jinja2 or another in conjunction with django?

Note: I know that Django has StreamingHttpResponse, but as I understand it only allows the view to send chunks. I want the template to be rendered in blocks and possibly return those blocks as StreamingHttpResponse

opengl – Close objects are only partially rendered – LWJGL

I am working on an LWJGL project and I have a strange problem: nearby objects are no longer fully rendered if I move away slightly. I'm not a big expert on OpenGL, so I can't figure out what is causing it.

Here are two photos of what I'm talking about:
pic1,
pic2

And here's a photo to prove that the objects are fully loaded:
http://prntscr.com/r7joyc

Code to load a texture

Code to initialize the window

I think the mistake is somewhere here

@Override
    public Texture loadTexture(String filename) {
        try (MemoryStack stack = MemoryStack.stackPush()) {
            //Height, width and colour channels are 1 byte each
            IntBuffer w = stack.mallocInt(1);
            IntBuffer h = stack.mallocInt(1);
            IntBuffer channels = stack.mallocInt(1);

            //Load image into the ByteBuffer
            this.byteBuffer = stbi_load(filename, w, h, channels, 4);
            if (this.byteBuffer == null) {
                throw new FileNotFoundException("Texture file (" + filename + ") not loaded. Reason: " + stbi_failure_reason());
            }

            //Get width and height of image
            this.width = w.get();
            this.height = h.get();

            int textureID = this.generateTexture();
            this.generateMipMap();
            this.clean();
            return new Texture(textureID, this.width, this.height);
        } catch (Exception e) {
            logger.error(e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    //For scaled textures
    private void generateMipMap() {
        glGenerateMipmap(GL_TEXTURE_2D);
    }

    private int generateTexture() {
        int textureId = glGenTextures();
        // Bind the texture
        glBindTexture(GL_TEXTURE_2D, textureId);
        //Tell OpenGL how to unpack RGBA. 1 byte for pixel
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
         /*Args:
              1. Type of texture;
              2. Number of colour components in the texture;
              3. Colour components in texture;
              4. Texture width;
              5. Texture height;
              6. Texture border size;
              7. Format of the pixel data (RGBA);
              8. Each pixel is represented by an unsigned int;
              9. Data to load is stored in a ByteBuffer
         */
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, this.width, this.height,
                0, GL_RGBA, GL_UNSIGNED_BYTE, this.byteBuffer);
        return textureId;
    }

    private void clean() {
        //Free ByteBuffer
        stbi_image_free(this.byteBuffer);
    } 

Or here

public void init() {
        // Setup an error callback. The default implementation
        // will print the error message in System.err.
        GLFWErrorCallback.createPrint(System.err).set();

        // Initialize GLFW. Most GLFW functions will not work before doing this.
        if (!glfwInit()) {
            throw new IllegalStateException("Unable to initialize GLFW");
        }

        glfwDefaultWindowHints(); // optional, the current window hints are already the default
        glfwWindowHint(GLFW_VISIBLE, GL_FALSE); // the window will stay hidden after creation
        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // the window will be resizable
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

        boolean maximized = false;
        // If no size has been specified set it to maximized state
        if (width == 0 || height == 0) {
            // Set up a fixed width and height so window initialization does not fail
            width = 100;
            height = 100;
            glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
            maximized = true;
        }

        windowHandle = glfwCreateWindow(width, height, title, NULL, NULL);
        // Create the window
        if (windowHandle == NULL) {
            throw new RuntimeException("Failed to create the GLFW window");
        }
        logger.trace("Window handle: " + windowHandle);
        // Setup resize callback
        glfwSetFramebufferSizeCallback(windowHandle, (window, width, height) -> {
            this.width = width;
            this.height = height;
            this.setResized(true);
        });

        // Setup a key callback. It will be called every time a key is pressed, repeated or released.
        glfwSetKeyCallback(windowHandle, (window, key, scancode, action, mods) -> {
            if (key == GLFW_KEY_ESCAPE && action == GLFW_RELEASE) {
                glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
            }
        });

        if (maximized) {
            glfwMaximizeWindow(windowHandle);
        } else {
            // Get the resolution of the primary monitor
            GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
            // Center our window
            glfwSetWindowPos(
                    windowHandle,
                    (vidmode.width() - width) / 2,
                    (vidmode.height() - height) / 2
            );
        }


        // Make the OpenGL context current
        glfwMakeContextCurrent(windowHandle);

        if (isvSync()) {
            // Enable v-sync
            glfwSwapInterval(1);
        }

        // Make the window visible
        glfwShowWindow(windowHandle);

        GL.createCapabilities();

        // Set the clear color
        setClearColor(clearColor.x, clearColor.y, clearColor.z, clearColor.w);

        glEnable(GL_DEPTH_TEST);

        // Support for transparencies
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);

        if(debug){
            glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
        }
    }
```

ios – Flatlist of videos is not rendered in reactive

I have a list of videos that are rendered and after 32 rendered videos I get the following error message:

domain: "AVFoundationErrorDomain", code: -11839

This is because iOS can only instantiate 32 video players at a time. Then how can I get rid of some of the video players? The flatlist is horizontal and is enclosed by a vertically scrolling recycler list view. The code for the flatlist is here:

       { this.flatListRef = ref }}
                    data={this.state.posts}
                    extraData={this.state}
                    onScroll={(e) => this.pauseAll(e)}
                    showsHorizontalScrollIndicator={false}
                    scrollEnabled={this.state.isPortrait}
                    horizontal={true}
                    renderAheadOffset={0}
                    initialNumToRender={3}
                    windowSize={3}
                    removeClippedSubviews={true}
                    pagingEnabled={true}
                    keyExtractor={(row, id) => id.toString()}
                    renderItem={(row, id) => (this.renderVideos())}
/>

8 – Caching a block through a custom entity that is rendered into

I'm having trouble caching a custom block correctly:

  • We have a custom unit "politician"
  • For this entity we have several routes where we want to render a "politician header" with some basic information about the politician
  • The politician header is a custom template that is rendered in a custom block
  • the problem is: if caching is activated, the block always shows the politician data of the first rendered politician.

Here is the code for the block plugin – to keep it simple, I don't copy the getPoliticianFromUrl () method here:

/**
 * Provides a block with the profile header for a politician. We do not render
 * it on the public edit form path
 *
 * @Block(
 *   id = "aw_frontend_politician_header",
 *   admin_label = @Translation("Politician profile header"),
 *   category = "Abgeordnetenwatch"
 * )
 */
class PoliticianProfileHeader extends BlockBase {
  /**
   * {@inheritdoc}
   */
  public function build() {
    $politician = $this->getPoliticianFromUrl();
    if ($politician == NULL) {
      return ();
    }

    return array(
      '#theme' => 'politician_header',
      '#politician' => $politician,
      '#cache' => (
        'keys' => ('politician', $politician->id())
      )
    );
  }

  public function getCacheContexts() {
    $politician = $this->getPoliticianFromUrl();
    if ($politician != NULL) {
      return Cache::mergeContexts(parent::getCacheContexts(), $politician->getCacheContexts());
    }
    return parent::getCacheContexts();
  }

  public function getCacheTags() {
    $politician = $this->getPoliticianFromUrl();
    if ($politician != NULL) {
      return Cache::mergeTags(parent::getCacheTags(), $politician->getCacheTags());
    }
    return parent::getCacheTags();
  }
}

Then I render the politician header – again I just inserted interesting parts:

function template_preprocess_politician_header(&$variables) {
  /** @var Drupalpw_basicEntityPolitician $politician */
  $politician = $variables('politician');
  /** @var DrupalCoreRenderRenderer $renderer */
  $renderer = Drupal::service('renderer');
  $renderer->addCacheableDependency($variables, $politician);
  $variables("#cache")("contexts")() = 'user.roles';
  $variables('#cache')('keys') = ('politician_header', $politician->id());
}

I thought that defining cache keys ensures that different versions of the render array are cached. This doesn't happen – not for the custom politician header template (for which I don't find cached data in cache_render tanle – is this only cached with twig caching?) And not for the block.

My idea was to create a custom cache context based on my politician entity. As far as I understand cache contexts, however, they depend on more general circumstances such as the active topic, the current user, and similar things. I was hoping the entity API would magically create such a context, so I tried $ politician-> getCacheContexts () but nothing.

What am i missing