Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blocks do not always translate #19

Open
NAllred91 opened this issue Oct 17, 2017 · 5 comments
Open

Blocks do not always translate #19

NAllred91 opened this issue Oct 17, 2017 · 5 comments

Comments

@NAllred91
Copy link

You can reproduce this in your live demo, http://mo4islona.github.io/blockly/

First, load the page and change the language to french. Open the the Loops flyout to see that the while block has been translated to french. Then close the flyout and translate back to english. Check the Loops flyout again and still see french in the While block.

It seems like these blocks are getting stuck on whatever language they are set to when you first look at them.

@NAllred91 NAllred91 changed the title Drop downs do not always translate Blocks do not always translate Oct 17, 2017
@NAllred91
Copy link
Author

I've got a hacky way I think I can fix this in my own fork of node-blockly. I'm not sure how what the correct way to fix this is yet.

@mo4islona
Copy link
Owner

mo4islona commented Oct 18, 2017

I know about this problem and think the problem is inside Blockly. Some blocks translates back correctly some not.
For example Test translates correctly in english after french.

They fixed some blocks – in earlier versions of Blockly no one blocks translated back.

@NAllred91
Copy link
Author

NAllred91 commented Oct 18, 2017

Ah yea... At first I thought it was only drop downs but now I see its all pretty random. I'll take a look at blockly at some point and see if I can do a PR there.

For the time being I'm working around this in my application by creating a blocklyStore.js:

module.exports = {
    Blockly: require('node-blockly/browser'),
    reset: function() {
        delete require.cache[require.resolve('node-blockly/browser')]
        delete require.cache[require.resolve('node-blockly/lib/blockly_compressed_browser')]
        delete require.cache[require.resolve('node-blockly/lib/blocks_compressed_browser')]
        this.Blockly = require('node-blockly/browser')
    },
}

Then to use Blockly I do:

var BS = require('blocklyStore')

BS.Blockly.inject(...

Then whenever I change languages I call BS.reset().

This seems to work fine as a work around for now.

@NAllred91
Copy link
Author

Turns out my work around wasn't quite enough...

This line causes problems..
https://github.com/mo4islona/node-blockly/blob/master/browser.js#L12

Since setLocale is always called initially with english, so even when you clear the require cache it still gets called with english from the start and that messes up some blocks.

I'm not sure if my current solution is good enough for a PR, but I changed browser.js to this

var getBlockly = function(languageCode) {
  delete require.cache[require.resolve('node-blockly/lib/blockly_compressed_browser')]
  delete require.cache[require.resolve('node-blockly/lib/blocks_compressed_browser')]
  var Blockly = require('./lib/blockly_compressed_browser');

  Blockly._setLocale = function(locale) {
    Blockly.Msg = Object.assign(locale, Blockly.Msg);
    Blockly.Msg = Blockly.Msg();
  }

  Blockly.utils.getMessageArray_ = function () {
    return Blockly.Msg
  }

  Blockly._setLocale(require('./lib/i18n/' + languageCode))

  Blockly.Blocks = Object.assign(Blockly.Blocks, require('./lib/blocks_compressed_browser')(Blockly));

  Blockly.JavaScript = require('./lib/javascript_compressed')(Blockly);
  Blockly.Lua = require('./lib/lua_compressed')(Blockly);
  Blockly.Dart = require('./lib/dart_compressed')(Blockly);
  Blockly.PHP = require('./lib/php_compressed')(Blockly);
  Blockly.Python = require('./lib/python_compressed')(Blockly);

  return Blockly
}

class Blockly {
  constructor() {
      Object.assign(this, getBlockly('en'))
  }

  setLanguage = (languageCode) => {
      Object.assign(this, getBlockly(languageCode))
  }
}

module.exports =  new Blockly()

Then, to change the language I do this

import Blockly from 'node-blockly/browser'

var changeLanguage = (languageCode) => {
    Blockly.setLanguage(languageCode)
    var currentXML = this._getWorkspaceXML()
    this._workspace.dispose()
    this._workspace = Blockly.inject(config.blocklyElementId, {
                toolbox: getToolbox(this._appManager),
                grid: config.blocklyGridOptions,
            })
    this._setWorkspaceXML(currentXML)
}

With this solution, Blockly._setLocale only ever gets called on a given instance of Blockly once.

@NAllred91
Copy link
Author

But this solution is nice because I can change the language without doing the weird cache invalidation in my own code.

If I made a PR using this pattern and cleaned it up some keeping Blockly.setLocale as the public method, I don't think it would break existing code that uses setLocale? Let me know if you're interested in a PR with this pattern.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants