Implement Yoast SEO for TYPO3 in your own extension

From version 2.0, Yoast SEO for TYPO3 has the possibility to add the analysis to your own records. In version 2 the plugin also had some configuration for EXT:news and EXT:cal shipped. In some cases there were errors in installations wich don't have those extensions installed, so we decided to remove this configuration. So from version 3.0 you need to integrate Yoast SEO for TYPO3 in your own extension yourself.

In this blogpost I will tell you how to integrate Yoast SEO for TYPO3 in your own extension.

So how to integrate Yoast SEO for TYPO3 in your own extension?

It is quite easy to do if you have some knowledge about TCA. I will guide you with some easy steps to add those fields to EXT:news records as an example.

First we start with adding the field for the keyword. You can add the following code to the ext_tables.sql of your own extension.

		#
# Table structure for table 'tx_news_domain_model_news'
#
CREATE TABLE tx_news_domain_model_news (
  tx_yoastseo_focuskeyword varchar(100) DEFAULT '' NOT NULL,
);
	

Don't forget to run your database updates in the Installtool or by a command line command after you added the field to the sql file. 

After you added the field to the database we need some TCA for the news table. You have to create a file Configuration/TCA/Overrides/tx_news_domain_model_news.php and can add the following code.

		<?php
$ll = 'LLL:EXT:your_ext/Resources/Private/Language/TCA.xlf:';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTCAcolumns(
    'tx_news_domain_model_news',
    [
        'tx_yoastseo_snippetpreview' => [
            'label' => $ll . 'snippetPreview',
            'exclude' => true,
            'displayCond' => 'REC:NEW:false',
            'config' => [
                'type' => 'text',
                'renderType' => 'snippetPreview',
                'settings' => [
                    'titleField' => 'alternative_title',
                    'descriptionField' => 'description'
                ]
            ]
        ],
        'tx_yoastseo_readability_analysis' => [
            'label' => $ll . 'analysis',
            'exclude' => true,
            'config' => [
                'type' => 'text',
                'renderType' => 'readabilityAnalysis'
            ]
        ],
        'tx_yoastseo_focuskeyword' => [
            'label' => $ll . 'seoFocusKeyword',
            'exclude' => true,
            'config' => [
                'type' => 'input',
            ]
        ],
        'tx_yoastseo_focuskeyword_analysis' => [
            'label' => $ll . 'analysis',
            'exclude' => true,
            'config' => [
                'type' => 'input',
                'renderType' => 'focusKeywordAnalysis',
                'settings' => [
                    'focusKeywordField' => 'tx_yoastseo_focuskeyword',
                ]
            ]
        ],

    ]
);

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette(
    'tx_news_domain_model_news',
    'yoast-metadata',
    '
    --linebreak--, tx_yoastseo_snippetpreview,
    '
);

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette(
    'tx_news_domain_model_news',
    'yoast-focuskeyword',
    '
    --linebreak--, tx_yoastseo_focuskeyword,
    --linebreak--, tx_yoastseo_focuskeyword_analysis
    '
);

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addFieldsToPalette(
    'tx_news_domain_model_news',
    'yoast-readability',
    '
    --linebreak--, tx_yoastseo_readability_analysis
    '
);

\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addToAllTCAtypes(
    'tx_news_domain_model_news',
    '
    --div--;' . $ll . 'pages.tabs.seo,
        --palette--;' . $ll . 'pages.palettes.metadata;yoast-metadata,
        --palette--;' . $ll . 'pages.palettes.readability;yoast-readability,
        --palette--;' . $ll . 'pages.palettes.seo;yoast-focuskeyword,
    ',
    '',
    'after:bodytext'
);
	

Define fields

A little explaination: from line 3 to 47, I add some fields. First of all I added the field with renderType snippetPreview. As you can guess, this will add the snippet preview to your record. In the settings part, you need to configure which fields to use for the title and which field for the description.

For showing the results of the readability analysis, I added the tx_yoastseo_readability_analysis field. Besides the correct renderType you don't need any thing else.

To check your news record if it scores good in search engines, you need two fields. First of all, I added a field to make it possible to add a keyword. This is the field you also added to your database before. In my case this is tx_yoastseo_focuskeyword. To be able to show the analysis you need a field with renderType focusKeywordAnalysis as well. In my case that is tx_yoastseo_focuskeyword_analysis. 

Show the fields

To group the pages I added the fields we defined in several palettes. This is just normal TCA and if you are familiar with palettes, this should not be a problem. Otherwise you can just use this example or have a look at the documentation about TCA palettes.

And to finish, we have to add the palettes to the view by using ExtensionManagementUtility::addToAllTCAtypes.

Configuring preview

The Yoast plugin uses the preview configuration to check the record in frontend. So it is important to have set the preview configuration for your record. For example for EXT:news, you can use the snippet from the manual of EXT:news. 

		TCEMAIN.preview {
    tx_news_domain_model_news {
        previewPageId = {pageIdOfYourDetailPage}
        useCacheHash = 1
        useDefaultLanguageRecord = 0
        fieldToParameterMap {
            uid = tx_news_pi1[news_preview]
        }
        additionalGetParameters {
            tx_news_pi1.controller = News
            tx_news_pi1.action = detail
        }
    }
}
	

Please change {pageIdOfYourDetailPage} to the page id of your detail page.

Now you have to make sure, the Yoast plugin gets the right data for the analysis. Below an example of what I did to make sure the Yoast can analyse my records.

		[globalVar = GP:tx_news_pi1|news > 0] || [globalVar = GP:tx_news_pi1|news_preview > 0]
    lib.yoastSEO {
        canonicalURL >
        og >
        twitter >

        pageTitle >
        pageTitle = RECORDS
        pageTitle {
            tables = tx_news_domain_model_news
            dontCheckPid = 1
            source = {GP:tx_news_pi1|news},{GP:tx_news_pi1|news_preview}
            source.insertData = 1

            conf.tx_news_domain_model_news = TEXT
            conf.tx_news_domain_model_news.field = alternative_title
            conf.tx_news_domain_model_news.ifEmpty.field = title
        }

        description >
        description = RECORDS
        description {
            tables = tx_news_domain_model_news
            source = {GP:tx_news_pi1|news},{GP:tx_news_pi1|news_preview}
            source.insertData = 1

            conf.tx_news_domain_model_news = TEXT
            conf.tx_news_domain_model_news.field = description
        }
    }
[global]
	

The configuration above is used for two parts. First of all it is for rendering meta tags at the frontend. Because EXT:news already render canonical-, OG- and Twitter-tags, we will make sure Yoast SEO doesn't do that. The title and description field is rendered by EXT:news as well, but we need those fields for the analysis, so we added them here. Based on the id of the news record, it will get the title and description of the record.

And now we test

We have configured everything so we should be able to see an analysis in backend. So go to the News administration module in the backend (or use the List module) and edit a news item. You should see a tab called Yoast SEO with the snippet preview like in the screenshot below.

I hope this example shows how you can integrate Yoast SEO for TYPO3 in your own extension. If you have any question, please contact me or ask your question in the TYPO3 Slack-channel #yoast-seo-for-typo3

If you don't want to do it yourself or want a real example? Take a look at my extension called Yoast SEO for TYPO3 - EXT:news that does the integration we discussed in this post.

Get in touch!

Do you have a question? Do you want to work together? Just send me a message and I will get in touch as soon as possible.

Send a message