diff --git a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php
index 5c7adb56fec76d7dcee10372c631e50424dfca5c..38b0e1d1235b6fc9e49a261cc3d38f54416622da 100644
--- a/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php
+++ b/typo3/sysext/backend/Classes/Preview/StandardContentPreviewRenderer.php
@@ -400,7 +400,8 @@ class StandardContentPreviewRenderer implements PreviewRendererInterface, Logger
      */
     protected function linkEditContent(string $linkText, $row): string
     {
-        if ($this->getBackendUser()->recordEditAccessInternals('tt_content', $row)) {
+        $backendUser = $this->getBackendUser();
+        if ($backendUser->check('tables_modify', 'tt_content') && $backendUser->recordEditAccessInternals('tt_content', $row)) {
             $urlParameters = [
                 'edit' => [
                     'tt_content' => [
diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php b/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php
index 4bffb76b62f63e42c9547409a87857e8ca224588..e0c4671496856083c509f91afc221035ed56643c 100644
--- a/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php
+++ b/typo3/sysext/backend/Classes/View/BackendLayout/BackendLayout.php
@@ -280,18 +280,13 @@ class BackendLayout
     public function getLanguageColumns(): iterable
     {
         if (empty($this->languageColumns)) {
-            $defaultLanguageElements = [];
-            $contentByColumn = $this->getContentFetcher()->getContentRecordsPerColumn(null, 0);
-            if (!empty($contentByColumn)) {
-                $defaultLanguageElements = array_merge(...$contentByColumn);
-            }
             foreach ($this->getDrawingConfiguration()->getSiteLanguages() as $siteLanguage) {
                 if (!in_array($siteLanguage->getLanguageId(), $this->getDrawingConfiguration()->getLanguageColumns())) {
                     continue;
                 }
                 $backendLayout = clone $this;
                 $backendLayout->getDrawingConfiguration()->setLanguageColumnsPointer($siteLanguage->getLanguageId());
-                $this->languageColumns[] = GeneralUtility::makeInstance(LanguageColumn::class, $backendLayout, $siteLanguage, $defaultLanguageElements);
+                $this->languageColumns[] = GeneralUtility::makeInstance(LanguageColumn::class, $backendLayout, $siteLanguage);
             }
         }
         return $this->languageColumns;
diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php b/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php
index 757ce29ab57f614bbd8475f911f25a5fab6b35bf..1d79bec530c27c79bfac3724b9c2866ac8635aef 100644
--- a/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php
+++ b/typo3/sysext/backend/Classes/View/BackendLayout/ContentFetcher.php
@@ -128,6 +128,16 @@ class ContentFetcher
         }
 
         if (!isset($this->languageHasTranslationsCache[$language])) {
+            if ($language) {
+                $contentRecordsInDefaultLanguage = $this->getContentRecordsPerColumn(null, 0);
+                if (!empty($contentRecordsInDefaultLanguage)) {
+                    $contentRecordsInDefaultLanguage = array_merge(...$contentRecordsInDefaultLanguage);
+                }
+            } else {
+                $contentRecordsInDefaultLanguage = $contentElements;
+            }
+            $untranslatedRecordUids = array_flip(array_column($contentRecordsInDefaultLanguage, 'uid'));
+
             foreach ($contentElements as $contentElement) {
                 if ((int)$contentElement['l18n_parent'] === 0) {
                     $this->languageHasTranslationsCache[$language]['hasStandAloneContent'] = true;
@@ -137,10 +147,14 @@ class ContentFetcher
                     $this->languageHasTranslationsCache[$language]['hasTranslations'] = true;
                     $this->languageHasTranslationsCache[$language]['mode'] = 'connected';
                 }
+                if ((int)$contentElement['l10n_source'] > 0) {
+                    unset($untranslatedRecordUids[(int)$contentElement['l10n_source']]);
+                }
             }
             if (!isset($this->languageHasTranslationsCache[$language])) {
                 $this->languageHasTranslationsCache[$language]['hasTranslations'] = false;
             }
+            $this->languageHasTranslationsCache[$language]['untranslatedRecordUids'] = array_keys($untranslatedRecordUids);
 
             // Check for inconsistent translations, force "mixed" mode and dispatch a FlashMessage to user if such a case is encountered.
             if (isset($this->languageHasTranslationsCache[$language]['hasStandAloneContent'])
diff --git a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php
index 4e0196813a4de17c23b2bdf7ab2a572b1135852b..3ee084a47b72ca5300a96fe7576ef1ed35bc8571 100644
--- a/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php
+++ b/typo3/sysext/backend/Classes/View/BackendLayout/Grid/LanguageColumn.php
@@ -54,23 +54,18 @@ class LanguageColumn extends AbstractGridObject
     /**
      * @var array
      */
-    protected $defaultLanguageElements = [];
-
-    /**
-     * @var array
-     */
-    protected $flatContentOfLanguage = [];
+    protected $localizationConfiguration = [];
 
     /**
      * @var GridColumn|null
      */
     protected $grid;
 
-    public function __construct(BackendLayout $backendLayout, SiteLanguage $language, array $defaultLanguageElements)
+    public function __construct(BackendLayout $backendLayout, SiteLanguage $language)
     {
         parent::__construct($backendLayout);
         $this->siteLanguage = $language;
-        $this->defaultLanguageElements = $defaultLanguageElements;
+        $this->localizationConfiguration = BackendUtility::getPagesTSconfig($backendLayout->getDrawingConfiguration()->getPageId())['mod.']['web_layout.']['localization.'] ?? [];
         if ($this->siteLanguage->getLanguageId() > 0) {
             $pageLocalizationRecord = BackendUtility::getRecordLocalization(
                 'pages',
@@ -85,14 +80,6 @@ class LanguageColumn extends AbstractGridObject
         } else {
             $this->localizedPageRecord = $backendLayout->getDrawingConfiguration()->getPageRecord();
         }
-
-        $contentFetcher = $backendLayout->getContentFetcher();
-        $contentRecords = $contentFetcher->getContentRecordsPerColumn(null, $language->getLanguageId());
-        if (!empty($contentRecords)) {
-            $this->flatContentOfLanguage = array_merge(...$contentRecords);
-        } else {
-            $this->flatContentOfLanguage = [];
-        }
     }
 
     public function getLocalizedPageRecord(): ?array
@@ -149,55 +136,18 @@ class LanguageColumn extends AbstractGridObject
 
     public function getAllowTranslate(): bool
     {
-        if ($this->siteLanguage->getLanguageId() === 0) {
-            return false;
-        }
-
-        $localizationTsConfig = BackendUtility::getPagesTSconfig($this->backendLayout->getDrawingConfiguration()->getPageId())['mod.']['web_layout.']['localization.'] ?? [];
-        $allowTranslate = (bool)($localizationTsConfig['enableTranslate'] ?? true);
-        if (!$allowTranslate) {
-            return false;
-        }
-
-        $translationData = $this->backendLayout->getContentFetcher()->getTranslationData($this->flatContentOfLanguage, $this->siteLanguage->getLanguageId());
-        if (!empty($translationData)) {
-            if (isset($translationData['hasStandAloneContent'])) {
-                return false;
-            }
-        }
-
-        $defaultLanguageUids = array_flip(array_column($this->defaultLanguageElements, 'uid'));
-        $translatedLanguageUids = array_column($this->flatContentOfLanguage, 'l10n_source');
-        if (empty($translatedLanguageUids)) {
-            return true;
-        }
-
-        foreach ($translatedLanguageUids as $translatedUid) {
-            unset($defaultLanguageUids[$translatedUid]);
-        }
-
-        return !empty($defaultLanguageUids);
+        return ($this->localizationConfiguration['enableTranslate'] ?? true) && !($this->getTranslationData()['hasStandAloneContent'] ?? false);
     }
 
     public function getTranslationData(): array
     {
         $contentFetcher = $this->backendLayout->getContentFetcher();
-        return $contentFetcher->getTranslationData($this->defaultLanguageElements, $this->siteLanguage->getLanguageId());
+        return $contentFetcher->getTranslationData($contentFetcher->getFlatContentRecords(), $this->siteLanguage->getLanguageId());
     }
 
     public function getAllowTranslateCopy(): bool
     {
-        $localizationTsConfig = BackendUtility::getPagesTSconfig($this->backendLayout->getDrawingConfiguration()->getPageId())['mod.']['web_layout.']['localization.'] ?? [];
-        $allowCopy = (bool)($localizationTsConfig['enableCopy'] ?? true);
-        if (!empty($translationData)) {
-            if (isset($translationData['hasStandAloneContent'])) {
-                return false;
-            }
-            if (isset($translationData['hasTranslations'])) {
-                $allowCopy = $allowCopy && !$translationData['hasTranslations'];
-            }
-        }
-        return $allowCopy;
+        return ($this->localizationConfiguration['enableCopy'] ?? true) && !($this->getTranslationData()['hasTranslations'] ?? false);
     }
 
     public function getTranslatePageTitle(): string
diff --git a/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php b/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php
index dace807aab1442a304985a8df8fda7b0ab2ceaaf..fe6b6ddaee425203028a7943880de10c9cea206e 100644
--- a/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php
+++ b/typo3/sysext/backend/Classes/View/Drawing/BackendLayoutRenderer.php
@@ -98,6 +98,7 @@ class BackendLayoutRenderer
         }
         $this->view->assign('newContentTitle', $this->getLanguageService()->getLL('newContentElement'));
         $this->view->assign('newContentTitleShort', $this->getLanguageService()->getLL('content'));
+        $this->view->assign('allowEditContent', $this->getBackendUser()->check('tables_modify', 'tt_content'));
 
         $rendered = $this->view->render('PageLayout');
         if ($renderUnused) {
diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html
index e1935eb681f165423cf6027a4a1664f18690b28c..838fa0d8be81c7966208b45942ec9f937c82087f 100644
--- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html
+++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Grid/Column.html
@@ -8,7 +8,7 @@
         <f:if condition="{column.active}">
             <f:then>
                 <div class="t3-page-column-header-icons">
-                    <f:if condition="{column.editUrl}">
+                    <f:if condition="{allowEditContent} && {column.editUrl}">
                         <a href="{column.editUrl}" title="{column.editLinkTitle}"><core:icon identifier="actions-document-open" /></a>
                     </f:if>
                 </div>
@@ -25,7 +25,7 @@
             </f:else>
         </f:if>
     </div>
-    <f:if condition="{column.contentEditable} && {grid.allowNewContent}">
+    <f:if condition="{allowEditContent} && {column.contentEditable} && {grid.allowNewContent}">
         <div class="t3-page-ce t3js-page-ce" data-page="{column.backendLayout.drawingConfiguration.pageId}" id="{column.uniqueId}">
             <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-{column.columnNumber}-page-{column.backendLayout.drawingConfiguration.pageId}-{column.uniqueId}">
                 <a href="{column.newContentUrl}" title="{newContentTitle}" data-title="{newContentTitle}"
diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html
index d7cbb286e89074670dd3f0d7198044a4264313bf..46711817a8029a05001c651efdc7336d52fa2d46 100644
--- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html
+++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/LanguageColumns.html
@@ -35,7 +35,7 @@
                                 <core:icon identifier="actions-open" />
                             </a>
                         </f:if>
-                        <f:if condition="{languageColumn.allowTranslate}">
+                        <f:if condition="{allowEditContent} && {languageColumn.siteLanguage.languageId} && {languageColumn.translationData.untranslatedRecordUids}">
                             <a href="#" class="btn btn-default btn-sm t3js-localize disabled"
                                 title="{languageColumn.translatePageTitle}"
                                 data-page="{languageColumn.localizedPageRecord.title}"
diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html
index 8dc2731d838612f9fda6f23a4f1c0a6d23d56b14..bfaaaeb252f9b3ea3d46e5b931c772ed936381ff 100644
--- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html
+++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record.html
@@ -2,7 +2,7 @@
 <div class="t3-page-ce {item.wrapperClassName} t3js-page-ce t3js-page-ce-sortable" id="element-tt_content-{item.record.uid}" data-table="tt_content" data-uid="{item.record.uid}" style="{style}">
     <div class="t3-page-ce-dragitem" id="{item.uniqueId}">
         <f:render partial="PageLayout/Record/{item.record.CType}/Header" optional="1">
-            <f:render partial="PageLayout/Record/Header" arguments="{item: item}" />
+            <f:render partial="PageLayout/Record/Header" arguments="{_all}" />
         </f:render>
         <div class="t3-page-ce-body">
             <div class="t3-page-ce-body-inner">
@@ -13,11 +13,11 @@
                 </div>
             </div>
             <f:render partial="PageLayout/Record/{item.record.CType}/Footer" optional="1">
-                <f:render partial="PageLayout/Record/Footer" arguments="{item: item}" />
+                <f:render partial="PageLayout/Record/Footer" arguments="{_all}" />
             </f:render>
         </div>
     </div>
-    <f:if condition="{item.column.contentEditable} && {grid.allowNewContent}">
+    <f:if condition="{allowEditContent} && {item.column.contentEditable} && {grid.allowNewContent}">
         <div class="t3js-page-new-ce t3-page-ce-wrapper-new-ce" id="colpos-{item.column.columnNumber}-page-{item.column.backendLayout.drawingConfiguration.pageId}-{item.column.uniqueId}">
             <a href="{item.newContentAfterUrl}" title="{item.newContentAfterLinkTitle}" data-title="{item.newContentAfterLinkTitle}" class="btn btn-default btn-sm t3js-toggle-new-content-element-wizard">
                 <core:icon identifier="actions-add" />
diff --git a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html
index 2cf6917020e772eba93b98aa92a095dac1811e76..4f3b5e74bdea6a40d1a153de48156284d0203b1c 100644
--- a/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html
+++ b/typo3/sysext/backend/Resources/Private/Partials/PageLayout/Record/Header.html
@@ -1,9 +1,9 @@
-<div class="t3-page-ce-header {f:if(condition: item.dragAndDropAllowed, then: 't3-page-ce-header-draggable t3js-page-ce-draghandle')}">
+<div class="t3-page-ce-header {f:if(condition: '{allowEditContent} && {item.dragAndDropAllowed}', then: 't3-page-ce-header-draggable t3js-page-ce-draghandle')}">
     <div class="t3-page-ce-header-icons-left">
         {item.icons -> f:format.raw()}
     </div>
     <div class="t3-page-ce-header-icons-right">
-        <f:if condition="{item.editable}">
+        <f:if condition="{item.editable} && {allowEditContent}">
             <div class="btn-toolbar">
                 <div class="btn-group btn-group-sm">
                     <a href="{item.editUrl}" class="btn btn-default">