Code development platform for open source projects from the European Union institutions :large_blue_circle: EU Login authentication by SMS has been phased out. To see alternatives please check here

Skip to content
Snippets Groups Projects
Commit e5eac11c authored by Davis Ragels's avatar Davis Ragels
Browse files

EMW Magento plugin Beta version

parent 82aebdde
Branches
Tags
No related merge requests found
Showing
with 451 additions and 0 deletions
node_modules
Emw/WebsiteTranslator/view/frontend/web/js/widget.js
\ No newline at end of file
<?php
namespace Emw\WebsiteTranslator\Block\Adminhtml;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Framework\App\Config\ScopeConfigInterface;
class Config extends Template {
protected $scopeConfig;
public function __construct( Context $context, ScopeConfigInterface $scopeConfig ) {
parent::__construct( $context );
$this->scopeConfig = $scopeConfig;
}
public function getTranslationHubUrl() {
return $this->scopeConfig->getValue( 'emw_general/emw_th_connection/url' );
}
public function getClientId() {
return $this->scopeConfig->getValue( 'emw_general/emw_th_connection/id' );
}
public function getJsConfig() {
$config = array(
'translationHubUrl' => $this->getTranslationHubUrl(),
'clientId' => $this->getClientId(),
);
return json_encode( $config );
}
}
<?php
namespace Emw\WebsiteTranslator\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Message\ManagerInterface as MessageManager;
class SaveSettingsObserver implements ObserverInterface {
protected $cacheManager;
protected $messageManager;
protected $config;
protected $curl;
public function __construct(
\Magento\Framework\App\Cache\Manager $cacheManager,
MessageManager $messageManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Framework\App\Config\ScopeConfigInterface $config,
) {
$this->cacheManager = $cacheManager;
$this->messageManager = $messageManager;
$this->config = $config;
$this->curl = $curl;
}
public function execute( Observer $observer ) {
// Check connection with Translation Hub.
$th_url = $this->config->getValue( 'emw_general/emw_th_connection/url' );
$id = $this->config->getValue( 'emw_general/emw_th_connection/id' );
$url = "$th_url/api/configurationservice/configuration/$id";
$this->curl->get( $url );
$statusCode = $this->curl->getStatus();
if ( 200 !== $statusCode ) {
$this->messageManager->addErrorMessage( 'There was an error connecting to Translation Hub. Please try again or recheck your configuration.' );
} else {
$this->messageManager->addSuccessMessage( 'Connection with Translation Hub successful.' );
}
// Clean cache.
$this->cacheManager->clean( array( 'compiled_config', 'full_page' ) );
}
}
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="emw_general" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>EMW Settings</label>
<tab>general</tab>
<resource>Emw_WebsiteTranslator::config</resource>
<group id="emw_th_connection" translate="label" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Connection with Translation Hub</label>
<field id="url" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1" required="true">
<label>Translation Hub URL</label>
<validate>required-entry validate-url</validate>
</field>
<field id="id" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1" required="true">
<label>Client ID</label>
<validate>required-entry</validate>
</field>
</group>
</section>
</system>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<csp_whitelist xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Csp:etc/csp_whitelist.xsd">
<policies>
<policy id="connect-src">
<values>
<value id="TH_API" type="host">localhost</value>
</values>
</policy>
</policies>
</csp_whitelist>
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="admin_system_config_changed_section_emw_general">
<observer name="emw_websitetranslator_save_settings" instance="Emw\WebsiteTranslator\Observer\SaveSettingsObserver" />
</event>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Emw_WebsiteTranslator" setup_version="1.0.0">
</module>
</config>
\ No newline at end of file
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Emw_WebsiteTranslator',
__DIR__
);
\ No newline at end of file
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="after.body.start">
<container name="website-translator" as="website-translator" label="WTW" htmlTag="div" htmlClass="website-translator" after="main.content">
<block class="Magento\Framework\View\Element\Text" name="comment.placeholder">
<!-- Add some comment as text value, because Magento does not create empty containers -->
<arguments>
<argument name="text" xsi:type="string"><![CDATA[<!-- Website translator widget -->]]></argument>
</arguments>
</block>
</container>
</referenceContainer>
<referenceContainer name="content">
<block class="Emw\WebsiteTranslator\Block\Adminhtml\Config" name="emw_config_block" template="Emw_WebsiteTranslator::emw_config.phtml" />
</referenceContainer>
</body>
</page>
\ No newline at end of file
var config = {
map: {
'*': {
'WebsiteTranslator': 'Emw_WebsiteTranslator/js/widget'
}
}
};
\ No newline at end of file
<script type="text/javascript">
require([
"WebsiteTranslator"
], function (WebsiteTranslator) {
var EMW_WEBSITETRANSLATOR_CONFIG = <?php /* @noEscape */ echo $block->getJsConfig(); ?>;
WebsiteTranslator.Options.api.clientId = EMW_WEBSITETRANSLATOR_CONFIG.clientId;
// Change backend url
WebsiteTranslator.Options.api.url = EMW_WEBSITETRANSLATOR_CONFIG.translationHubUrl;
WebsiteTranslator.Options.ui.branding.name = "EMW";
WebsiteTranslator.Options.ui.branding.url = "/";
WebsiteTranslator.Options.ui.toolbarPosition = "top";
// Display the language selector as a dropdown:
// menu - "menu"
// list of buttons - "list"
WebsiteTranslator.Options.ui.layout = "menu";
// Display UI in the language your visitors are translating into:
// target language - "target",
// the original language - "source"
WebsiteTranslator.Options.ui.translate = "target";
WebsiteTranslator.Initialize();
});
</script>
\ No newline at end of file
/*! PLACEHOLDER */
\ No newline at end of file
# EMW Magento extension
Website translation extension for Magento Open Source, that automatically translates every frontend page by including Javascript EMW website translation widget. This widget connects with a Translation Hub, which contains website translation configuration, machine-translation and translation editing capabilities.
## Dependencies
- **Translation Hub** (TH) - a service that communicates with the JS widget, providing selected language list and translations to HTML page source texts. Before setting up this Magento extension, TH must be set up and website integration data (source, target languages, MT provider information) must be added to it. TH must be accessible from your Magento website via HTTPS. You can set up your own TH instance or use any publicly available instance. To link this extension with the TH, you will need to provide TH URL and integration Client ID (generated by TH) in the extension settings.
## Solution architecture
![Architecture](architecture.png)
## Installation
1. Run `npm install`
2. **(Optional)** Add Translation Hub URL to CSP whitelist, if it is not allowed by Content Security Policy:
- Change `localhost` to your custom URL in `Emw/WebsiteTranslator/etc/csp_whitelist.xml`
2. Copy `Emw` folder to `[Magento root dir]/app/code/`
3. SSH into Magento instance and execute:
3.1. Change workdir to `[Magento root dir]`
3.2. Enable Emw_WebsiteTranslator module: `php bin/magento module:enable Emw_WebsiteTranslator`
3.3. Update DB: `php bin/magento setup:upgrade`
3.4. Clean cache: `php bin/magento cache:clean`
3.5. Generate classes: `php bin/magento setup:di:compile`
3.6. **(Optional)** Fix permissions for `[Magento root dir]/var` folder, if they have changed after executing any of previous commands (See: https://magento.stackexchange.com/questions/209373/missing-permission-in-var-folders-after-enable-module).
- e.g. for Apache: `chown -R daemon:root [Magento root dir]/var/`
4. Restart Magento instance
## Extension configuration
1. Open Admin panel
2. Go to Stores -> Configuration
3. Under tab `General` open `EMW Settings`
4. Enter Translation Hub URL, Client ID and click `Save Config`
5. Open any frontend page, EMW Website translation widget should be visible on the top of every page.
## Screenshots
| ![Settings](settings.png) |
|:--:|
| *Extension settings* |
| ![Frontend view](translation.png) |
|:--:|
| *Frontend view* |
## Licence
This extension is licensed under Open Software License (OSL) v3.0
\ No newline at end of file
architecture.png

230 KiB

# Build & Package plugin as a Zip archive
variables:
- name: PackageName
value: Emw
trigger:
- main
pool:
name: default
workspace:
clean: all
# npm install --ignore-scripts
steps:
- task: Npm@1
inputs:
command: 'custom'
workingDir: '$(Build.SourcesDirectory)'
customCommand: 'install --ignore-scripts'
displayName: 'Run npm install task'
# Do the custom script step ignored in Npm@1 task
- task: PowerShell@2
inputs:
targetType: 'inline'
script: 'copy-item .\node_modules\@tilde-nlp\website-translator\dist\widget.js -Destination .\Emw\WebsiteTranslator\view\frontend\web\js\ -Force'
failOnStderr: true
showWarnings: true
workingDirectory: '$(Build.SourcesDirectory)'
displayName: 'Copy node_modules/@tilde-nlp/website-translator/dist/widget.js to Emw/WebsiteTranslator/view/frontend/web/js/'
- task: ArchiveFiles@2
inputs:
rootFolderOrFile: '$(Build.SourcesDirectory)/$(PackageName)'
includeRootFolder: true
archiveType: 'zip'
archiveFile: '$(Build.ArtifactStagingDirectory)/$(PackageName).zip'
replaceExistingArchive: true
displayName: 'Create a Zip file'
- task: PublishBuildArtifacts@1
inputs:
PathtoPublish: '$(Build.ArtifactStagingDirectory)'
ArtifactName: 'plugin'
publishLocation: 'FilePath'
TargetPath: '\\tilde.lv\ad\Builds\MT\$(Build.DefinitionName)\$(Build.BuildNumber)'
displayName: 'Publish build to share'
\ No newline at end of file
{
"name": "emw-magento",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"hasInstallScript": true,
"dependencies": {
"@tilde-nlp/website-translator": "^7.1.3"
}
},
"node_modules/@babel/polyfill": {
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz",
"integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==",
"deprecated": "🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.",
"dependencies": {
"core-js": "^2.6.5",
"regenerator-runtime": "^0.13.4"
}
},
"node_modules/@babel/polyfill/node_modules/core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
"deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
"hasInstallScript": true
},
"node_modules/@tilde-nlp/website-translator": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@tilde-nlp/website-translator/-/website-translator-7.1.3.tgz",
"integrity": "sha512-H3Z1tizMmQRHD0Kbg35XaY0FSxo/Q4XihK+GTzQPVAkAcjG5Zuto92ZfUpvy+ZP++PkiN7M09wpxhDE92Ch2Pw==",
"dependencies": {
"@babel/polyfill": "^7.12.1",
"axios": "^0.25.0",
"core-js": "^3.21.1",
"rxjs": "^7.5.5"
}
},
"node_modules/axios": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
"dependencies": {
"follow-redirects": "^1.14.7"
}
},
"node_modules/core-js": {
"version": "3.30.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz",
"integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==",
"hasInstallScript": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/core-js"
}
},
"node_modules/follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/tslib": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA=="
}
},
"dependencies": {
"@babel/polyfill": {
"version": "7.12.1",
"resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.12.1.tgz",
"integrity": "sha512-X0pi0V6gxLi6lFZpGmeNa4zxtwEmCs42isWLNjZZDE0Y8yVfgu0T2OAHlzBbdYlqbW/YXVvoBHpATEM+goCj8g==",
"requires": {
"core-js": "^2.6.5",
"regenerator-runtime": "^0.13.4"
},
"dependencies": {
"core-js": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
"integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ=="
}
}
},
"@tilde-nlp/website-translator": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@tilde-nlp/website-translator/-/website-translator-7.1.3.tgz",
"integrity": "sha512-H3Z1tizMmQRHD0Kbg35XaY0FSxo/Q4XihK+GTzQPVAkAcjG5Zuto92ZfUpvy+ZP++PkiN7M09wpxhDE92Ch2Pw==",
"requires": {
"@babel/polyfill": "^7.12.1",
"axios": "^0.25.0",
"core-js": "^3.21.1",
"rxjs": "^7.5.5"
}
},
"axios": {
"version": "0.25.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.25.0.tgz",
"integrity": "sha512-cD8FOb0tRH3uuEe6+evtAbgJtfxr7ly3fQjYcMcuPlgkwVS9xboaVIpcDV+cYQe+yGykgwZCs1pzjntcGa6l5g==",
"requires": {
"follow-redirects": "^1.14.7"
}
},
"core-js": {
"version": "3.30.2",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz",
"integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg=="
},
"follow-redirects": {
"version": "1.15.2",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz",
"integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA=="
},
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
},
"rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"requires": {
"tslib": "^2.1.0"
}
},
"tslib": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA=="
}
}
}
{
"dependencies": {
"@tilde-nlp/website-translator": "^7.1.3"
},
"scripts": {
"postinstall": "cp ./node_modules/@tilde-nlp/website-translator/dist/widget.js ./Emw/WebsiteTranslator/view/frontend/web/js/"
}
}
settings.png

49 KiB

translation.png

20.1 KiB

0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment