From 2665a4dbc077e72541c739cab72963c4fd76b4f8 Mon Sep 17 00:00:00 2001 From: Shadi Naif Date: Mon, 14 Aug 2023 14:03:43 +0300 Subject: [PATCH] feat: add atlas support for cookiecutter-xblock Update cookiecutter-xblock to support atlas for all new XBlocks Refs: FC-0012 OEP-58 --- cookiecutter-xblock/cookiecutter.json | 7 +++--- cookiecutter-xblock/hooks/post_gen_project.py | 1 + cookiecutter-xblock/hooks/pre_gen_project.py | 13 ++++++++++ .../{{cookiecutter.repo_name}}/Makefile | 24 +++++++------------ .../{{cookiecutter.repo_name}}/README.rst | 2 +- .../{{cookiecutter.repo_name}}/manage.py | 2 +- .../{ => conf}/locale/__init__.py | 0 .../{ => conf}/locale/config.yaml | 0 .../{ => conf}/locale/settings.py | 7 +++++- .../js/src/{{cookiecutter.package_name}}.js | 5 ++++ lib/src/edx_cookiecutter_lib/post_code.py | 9 ++++++- 11 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 cookiecutter-xblock/hooks/pre_gen_project.py rename cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/{ => conf}/locale/__init__.py (100%) rename cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/{ => conf}/locale/config.yaml (100%) rename cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/{ => conf}/locale/settings.py (82%) diff --git a/cookiecutter-xblock/cookiecutter.json b/cookiecutter-xblock/cookiecutter.json index 315410c2..a948db98 100644 --- a/cookiecutter-xblock/cookiecutter.json +++ b/cookiecutter-xblock/cookiecutter.json @@ -1,9 +1,10 @@ { "project_desc": "My First XBlock", - "package_name": "myxblock", + "package_name": "my_xblock", + "i18n_namespace": "{{cookiecutter.package_name.split('_')|map('capitalize')|join('')}}I18n", "github_org": "openedx", - "repo_name": "{{cookiecutter.package_name}}-xblock", - "tag_name": "myxblock", + "repo_name": "{{cookiecutter.package_name.replace('_', '-')}}", + "tag_name": "{{cookiecutter.package_name|lower}}", "version": "0.1.0", "class_name": "MyXBlock", "author_name": "Open edX Project", diff --git a/cookiecutter-xblock/hooks/post_gen_project.py b/cookiecutter-xblock/hooks/post_gen_project.py index c946996e..7f5fd1fe 100644 --- a/cookiecutter-xblock/hooks/post_gen_project.py +++ b/cookiecutter-xblock/hooks/post_gen_project.py @@ -28,4 +28,5 @@ "setup_py_loading_pkg_data": "yes", "setup_py_keyword_args": setup_py_keyword_args, }, + symlink_translation=True, ) diff --git a/cookiecutter-xblock/hooks/pre_gen_project.py b/cookiecutter-xblock/hooks/pre_gen_project.py new file mode 100644 index 00000000..c9476d4d --- /dev/null +++ b/cookiecutter-xblock/hooks/pre_gen_project.py @@ -0,0 +1,13 @@ +""" +Verify that project info is valid +""" +import sys + + +if '{{ cookiecutter.package_name }}' == 'xblock': # pylint: disable=comparison-of-constants + print('ERROR: xblock is not a valid Python module name!') + sys.exit(1) + +if '{{ cookiecutter.i18n_namespace }}' == '{{ cookiecutter.package_name }}': # pylint: disable=comparison-of-constants + print('ERROR: (i18n_namespace) cannot be the same as (package_name)!') + sys.exit(1) diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/Makefile b/cookiecutter-xblock/{{cookiecutter.repo_name}}/Makefile index c08043c9..aaa50636 100644 --- a/cookiecutter-xblock/{{cookiecutter.repo_name}}/Makefile +++ b/cookiecutter-xblock/{{cookiecutter.repo_name}}/Makefile @@ -3,16 +3,12 @@ .PHONY: dev.clean dev.build dev.run upgrade help requirements .PHONY: extract_translations compile_translations .PHONY: detect_changed_source_translations dummy_translations build_dummy_translations -.PHONY: validate_translations pull_translations push_translations symlink_translations install_transifex_clients +.PHONY: validate_translations pull_translations push_translations install_transifex_clients REPO_NAME := {{cookiecutter.repo_name}} PACKAGE_NAME := {{cookiecutter.package_name}} -EXTRACT_DIR := $(PACKAGE_NAME)/locale/en/LC_MESSAGES -EXTRACTED_DJANGO := $(EXTRACT_DIR)/django-partial.po -EXTRACTED_DJANGOJS := $(EXTRACT_DIR)/djangojs-partial.po -EXTRACTED_TEXT := $(EXTRACT_DIR)/text.po -JS_TARGET := public/js/translations -TRANSLATIONS_DIR := $(PACKAGE_NAME)/translations +EXTRACT_DIR := $(PACKAGE_NAME)/conf/locale/en/LC_MESSAGES +JS_TARGET := $(PACKAGE_NAME)/public/js/translations help: @perl -nle'print $& if m{^[\.a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}' @@ -57,14 +53,13 @@ dev.run: dev.clean dev.build ## Clean, build and run test image ## Localization targets -extract_translations: symlink_translations ## extract strings to be translated, outputting .po files - cd $(PACKAGE_NAME) && i18n_tool extract - mv $(EXTRACTED_DJANGO) $(EXTRACTED_TEXT) - if [ -f "$(EXTRACTED_DJANGOJS)" ]; then cat $(EXTRACTED_DJANGOJS) >> $(EXTRACTED_TEXT); rm $(EXTRACTED_DJANGOJS); fi +extract_translations: ## extract strings to be translated, outputting .po files + cd $(PACKAGE_NAME) && i18n_tool extract --no-segment --merge-po-files + mv $(EXTRACT_DIR)/django.po $(EXTRACT_DIR)/text.po -compile_translations: symlink_translations ## compile translation files, outputting .mo files for each supported language +compile_translations: ## compile translation files, outputting .mo files for each supported language cd $(PACKAGE_NAME) && i18n_tool generate - python manage.py compilejsi18n --namespace $(PACKAGE_NAME)i18n --output $(JS_TARGET) + python manage.py compilejsi18n --namespace {{cookiecutter.i18n_namespace}} --output $(JS_TARGET) detect_changed_source_translations: cd $(PACKAGE_NAME) && i18n_tool changed @@ -82,9 +77,6 @@ pull_translations: ## pull translations from transifex push_translations: extract_translations ## push translations to transifex cd $(PACKAGE_NAME) && i18n_tool transifex push -symlink_translations: - if [ ! -d "$(TRANSLATIONS_DIR)" ]; then ln -s locale/ $(TRANSLATIONS_DIR); fi - install_transifex_client: ## Install the Transifex client # Instaling client will skip CHANGELOG and LICENSE files from git changes # so remind the user to commit the change first before installing client. diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/README.rst b/cookiecutter-xblock/{{cookiecutter.repo_name}}/README.rst index 76e65011..9c91e7cf 100644 --- a/cookiecutter-xblock/{{cookiecutter.repo_name}}/README.rst +++ b/cookiecutter-xblock/{{cookiecutter.repo_name}}/README.rst @@ -69,7 +69,7 @@ These catalogs can be created by running:: $ make extract_translations The previous command will create the necessary ``.po`` files under -``{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/en/LC_MESSAGES/text.po``. +``{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/en/LC_MESSAGES/text.po``. The ``text.po`` file is created from the ``django-partial.po`` file created by ``django-admin makemessages`` (`makemessages documentation `_), this is why you will not see a ``django-partial.po`` file. diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/manage.py b/cookiecutter-xblock/{{cookiecutter.repo_name}}/manage.py index aebd4025..6457b212 100755 --- a/cookiecutter-xblock/{{cookiecutter.repo_name}}/manage.py +++ b/cookiecutter-xblock/{{cookiecutter.repo_name}}/manage.py @@ -13,7 +13,7 @@ if __name__ == "__main__": os.environ.setdefault( "DJANGO_SETTINGS_MODULE", - "{{cookiecutter.package_name}}.locale.settings" + "{{cookiecutter.package_name}}.conf.locale.settings" ) execute_from_command_line(sys.argv) diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/__init__.py b/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/__init__.py similarity index 100% rename from cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/__init__.py rename to cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/__init__.py diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/config.yaml b/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/config.yaml similarity index 100% rename from cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/config.yaml rename to cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/config.yaml diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/settings.py b/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/settings.py similarity index 82% rename from cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/settings.py rename to cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/settings.py index cba1a0cd..8047b6a3 100644 --- a/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/locale/settings.py +++ b/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/conf/locale/settings.py @@ -7,6 +7,8 @@ """ import os +BASE_DIR = os.path.dirname(os.path.dirname(__file__)) + SECRET_KEY = os.getenv('DJANGO_SECRET', 'open_secret') # Application definition @@ -38,9 +40,12 @@ # statici18n # https://django-statici18n.readthedocs.io/en/latest/settings.html +LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale')] + STATICI18N_DOMAIN = 'text' +STATICI18N_NAMESPACE = '{{cookiecutter.i18n_namespace}}' STATICI18N_PACKAGES = ( - '{{cookiecutter.package_name}}.translations', + '{{cookiecutter.package_name}}', ) STATICI18N_ROOT = '{{cookiecutter.package_name}}/public/js' STATICI18N_OUTPUT_DIR = 'translations' diff --git a/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/static/js/src/{{cookiecutter.package_name}}.js b/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/static/js/src/{{cookiecutter.package_name}}.js index 2284a094..e27ccea6 100644 --- a/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/static/js/src/{{cookiecutter.package_name}}.js +++ b/cookiecutter-xblock/{{cookiecutter.repo_name}}/{{cookiecutter.package_name}}/static/js/src/{{cookiecutter.package_name}}.js @@ -24,5 +24,10 @@ function {{cookiecutter.class_name}}(runtime, element) { */ /* Here's where you'd do things on page load. */ + + // dummy_text is to have at least one string to translate in JS files. If you remove this line, + // and you don't have any other string to translate in JS files; then you must remove the (--merge-po-files) + // option from the "extract_translations" command in the Makefile + const dummy_text = gettext("Hello World"); }); } diff --git a/lib/src/edx_cookiecutter_lib/post_code.py b/lib/src/edx_cookiecutter_lib/post_code.py index 55d3b0a3..82d86c38 100644 --- a/lib/src/edx_cookiecutter_lib/post_code.py +++ b/lib/src/edx_cookiecutter_lib/post_code.py @@ -31,7 +31,7 @@ def move(src, dest): EDX_COOKIECUTTER_ROOTDIR = os.getenv('EDX_COOKIECUTTER_ROOTDIR') or 'https://github.com/openedx/edx-cookiecutters.git' -def post_gen_project(extra_context): +def post_gen_project(extra_context, symlink_translation=False): """ Most of what's needed after generating a project. @@ -71,3 +71,10 @@ def post_gen_project(extra_context): print(f"Since your repo will be in the {org} organization, you may need") print("to adjust the contents of the repo, such as licenses, email addresses,") print("and contribution details. Check with your organization.") + + if symlink_translation: + package_name = extra_context["sub_dir_name"] + source_path = os.path.join(project_root_dir, package_name, "conf", "locale") + target_path = os.path.join(project_root_dir, package_name, "translation") + + os.symlink(source_path, target_path)