logo

额外区块类型 (EBT) - 全新的布局构建器体验❗

额外区块类型 (EBT) - 样式化、可定制的区块类型:幻灯片、标签页、卡片、手风琴等更多类型。内置背景、DOM Box、JavaScript 插件的设置。立即体验布局构建的未来。

演示 EBT 模块 下载 EBT 模块

❗额外段落类型 (EPT) - 全新的 Paragraphs 体验

额外段落类型 (EPT) - 类似的基于 Paragraph 的模块集合。

演示 EPT 模块 滚动

滚动

Drupal 8 中的 Composer:从 Twitter 获取最新推文

16/10/2025, by Ivan

安装模块和库时,最好使用 Composer。Composer 是一个 PHP 库管理器,它允许你管理库和模块之间的依赖关系。如果一个模块依赖于某个库,Composer 会在安装模块时自动下载该库。虽然 Composer 在某种程度上增加了安装步骤,但它极大地简化了库的安装和加载过程,因为一切都将自动完成。

要下载并安装 Composer,请访问官方网站:

https://getcomposer.org/download/

顺便说一下,Drush 现在也通过 Composer 安装。如果你已经安装过 Drush,那么系统中已经有 Composer。可以通过以下命令验证是否安装成功:

composer --version

结果应显示 Composer 的版本:

drupal composer

现在,进入你的网站目录并通过控制台使用 Composer。

在 Drupal 8 中显示 Twitter 最新推文

首先,你需要在 Twitter 上创建一个应用程序(application),以获取一组令牌(tokens)用于 API 授权。创建应用程序的页面:

https://apps.twitter.com/

Twitter API 1.0 版本 即将被弃用,未授权请求将被拒绝。因此,建议使用 1.1 或更高版本的 Twitter API。

1. 创建开发者账户。请在 Twitter 上注册并配置你的 开发者账户

填写注册表单,这是免费的,也是使用 Twitter API 1.1 的必备步骤。然后前往 My Apps 页面并点击 “Create New App”:

twitter app block

2. 创建 Twitter 应用程序。填写表单时需输入你的网站域名。

drupal

如果成功创建应用程序,你将被重定向到应用页面。接下来,你需要以下数据:

  • Consumer key
  • Consumer secret
  • Access token
  • Access token secret

Twitter API 文档详细说明了这些令牌的作用及使用方法:https://dev.twitter.com/oauth/overview/single-user

3. 生成 Access Token。Twitter 使用 OAuth 协议,因此需要生成多个令牌。

Drupal

这将生成 Access TokenAccess Token Secret,稍后将在 Drupal 模块中使用。

接下来,我们可以通过 Twitter API 获取推文。虽然可以直接使用 drupal_http_request 请求,但更推荐使用现成的 Twitter 库来简化工作。如果 API 升级,只需更新库即可保持兼容。

本文使用以下 PHP 库:

https://packagist.org/packages/j7mbo/twitter-api-php

使用 Composer 安装该库:

composer require j7mbo/twitter-api-php

Composer 将自动下载库及其依赖项,你可以立即在代码中使用。

以下是用于在区块中显示最新推文的自定义模块代码。密钥和令牌存放在配置表单中:

/admin/structure/twitter-block/settings

模块代码可在本文附件或 Github 上获取:

https://github.com/Drupalbook/bootstrap

模块文件结构:

/modules/twitter_block/twitter_block.info.yml — 模块信息文件:

name: Twitter Block
description: Display Last tweets.
type: module
core: 8.x
package: Custom

/modules/twitter_block/src/Plugin/Block/TwitterBlock.php — 区块插件:

<?php
namespace Drupal\twitter_block\Plugin\Block;
use Drupal\Core\Block\BlockBase;

/**
 * Provides a Last tweet block.
 *
 * @Block(
 *   id = "twitter_block",
 *   admin_label = @Translation("Twitter block"),
 * )
 */
class TwitterBlock extends BlockBase {
  public function build() {
    $content = '';
    $config = \Drupal::config('twitter_block.settings');
    $settings = [
      'consumer_key' => $config->get('consumer_key'),
      'consumer_secret' => $config->get('consumer_secret'),
      'oauth_access_token' => $config->get('access_token'),
      'oauth_access_token_secret' => $config->get('access_token_secret'),
    ];

    $screen_name = 'netglooweb';
    $url = 'https://api.twitter.com/1.1/statuses/user_timeline.json';
    $getfield = "?count=1";
    $requestMethod = 'GET';

    $twitter = new \TwitterAPIExchange($settings);
    $user_timeline = $twitter
      ->setGetfield($getfield)
      ->buildOauth($url, $requestMethod)
      ->performRequest();

    $messages = json_decode($user_timeline);
    if (!empty($messages)) {
      foreach ($messages as $message) {
        $content .= '<div class="twitter-message">' . $message->text . '</div>';
      }
    }
    return ['#markup' => $content];
  }
}

/modules/twitter_block/src/Form/TwitterBlockSettingsForm.php — 配置表单:

<?php
namespace Drupal\twitter_block\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;

class TwitterBlockSettingsForm extends ConfigFormBase {
  public function getFormId() {
    return 'twitter_block_admin_settings';
  }

  protected function getEditableConfigNames() {
    return ['twitter_block.settings'];
  }

  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('twitter_block.settings');

    $form['consumer_key'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Consumer key'),
      '#default_value' => $config->get('consumer_key'),
    ];
    $form['consumer_secret'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Consumer secret'),
      '#default_value' => $config->get('consumer_secret'),
    ];
    $form['access_token'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Access token'),
      '#default_value' => $config->get('access_token'),
    ];
    $form['access_token_secret'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Access token secret'),
      '#default_value' => $config->get('access_token_secret'),
    ];

    return parent::buildForm($form, $form_state);
  }

  public function submitForm(array &$form, FormStateInterface $form_state) {
    $this->config('twitter_block.settings')
      ->set('consumer_key', $form_state->getValue('consumer_key'))
      ->set('consumer_secret', $form_state->getValue('consumer_secret'))
      ->set('access_token', $form_state->getValue('access_token'))
      ->set('access_token_secret', $form_state->getValue('access_token_secret'))
      ->save();

    parent::submitForm($form, $form_state);
  }
}

/modules/twitter_block/twitter_block.routing.yml — 配置表单路由:

twitter_block.settings:
  path: '/admin/structure/twitter-block/settings'
  defaults:
    _form: '\Drupal\twitter_block\Form\TwitterBlockSettingsForm'
    _title: 'Twitter API Settings'
  requirements:
    _permission: 'administer site configuration'

/modules/twitter_block/composer.json — 定义模块对库 j7mbo/twitter-api-php 的依赖:

{
  "name": "drupal/twitter_block",
  "type": "drupal-module",
  "description": "Displays Last tweets.",
  "homepage": "https://drupalbook.org/ru/drupal/composer-v-drupal-8-vyvod-poslednih-tvitov-iz-twitter",
  "license": "GPL-2.0+",
  "require": {
    "j7mbo/twitter-api-php": "dev-master"
  },
  "minimum-stability": "dev"
}

Github 源码地址:

https://github.com/levmyshkin/twitter_block