Skip to content

[BB-933] Allow overriding xblock icons with plugins - #21433

Merged
kdmccormick merged 1 commit into
openedx:masterfrom
open-craft:agrendalath/custom-icons
Apr 7, 2021
Merged

[BB-933] Allow overriding xblock icons with plugins#21433
kdmccormick merged 1 commit into
openedx:masterfrom
open-craft:agrendalath/custom-icons

Conversation

@Agrendalath

@Agrendalath Agrendalath commented Aug 23, 2019

Copy link
Copy Markdown
Member

This is a follow-up to #19772, which allowed setting custom icons for each unit in Studio. By default the icon would be derived from unit's type. The suggestion was to do move it to a plugin. This PR introduces some changes required to move it to external Django application

Most of this diff is about extracting modals from monolithic cms/static/js/views/modals/course_outline_modals.js to make them reusable. We also extracted CourseOutlineView class into a field in cms/static/js/views/pages/course_outline.js to make this view easily extendable.

For overriding implementation of getting icon, we implemented pluggable_override decorator.

JIRA tickets: OSPR-3801

Merge deadline: None

Sandbox: https://pr21433.sandbox.opencraft.hosting/ (provisioning)

Testing instructions:

  1. Go to this page and see that the first unit icon is fa-book.
  2. Install the master version of edx-django-utils in LMS (make lms-shell):
    pip install -e git+https://github.com/edx/edx-django-utils.git#egg=edx-django-utils
  3. Install custom-unit-icons for LMS (make lms-shell):
    pip install -e git+https://github.com/open-craft/custom-unit-icons.git@agrendalath/bb-933-address_override_changes#egg=custom-unit-icons
  4. Set the following in lms/envs/private.py and run make lms-restart:
    from .common import XBLOCK_MIXINS
    OVERRIDE_GET_UNIT_ICON = 'custom_unit_icons.icons.get_icon'
    XBLOCK_MIXINS += ('custom_unit_icons.icons.IconOverrideMixin',)
    
  5. Go to this page and see that the first unit icon is still fa-book.
  6. Run the following snippet in LMS Django shell:
    from xmodule.modulestore.django import modulestore
    from opaque_keys.edx.keys import UsageKey
    
    usage_key = UsageKey.from_string('block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec')
    item = modulestore().get_item(usage_key)
    item.icon_override = 'video'
    modulestore().update_item(item, 1)
  7. Go to this page and see that the first unit icon is now fa-film.

Reviewers

Settings

EDXAPP_EXTRA_REQUIREMENTS:
  - name: git+https://github.com/open-craft/custom-unit-icons.git@agrendalath/bb-933-address_override_changes#egg=custom-unit-icons
  - name: git+https://github.com/edx/edx-django-utils.git@master#egg=edx-django-utils

OVERRIDE_GET_UNIT_ICON: custom_unit_icons.icons.get_icon
XBLOCK_EXTRA_MIXINS:
    - custom_unit_icons.icons.IconOverrideMixin

TODO:

@Agrendalath
Agrendalath requested a review from a team August 23, 2019 12:36
@openedx-webhooks

openedx-webhooks commented Aug 23, 2019

Copy link
Copy Markdown

Thanks for the pull request, @Agrendalath! I've created OSPR-3801 to keep track of it in JIRA, where we prioritize reviews. Please note that it may take us up to several weeks or months to complete a review and merge your PR.

Feel free to add as much of the following information to the ticket:

  • supporting documentation
  • Open edX discussion forum threads
  • timeline information ("this must be merged by XX date", and why that is)
  • partner information ("this is a course on edx.org")
  • any other information that can help Product understand the context for the PR

All technical communication about the code itself will be done via the GitHub pull request interface. As a reminder, our process documentation is here.

Please let us know once your PR is ready for our review and all tests are green.

@natabene

Copy link
Copy Markdown
Contributor

@Agrendalath Thank you for your contribution. Please let me know once it is ready for our review.

@openedx-webhooks openedx-webhooks added waiting on author PR author needs to resolve review requests, answer questions, fix tests, etc. and removed needs triage labels Aug 23, 2019

@viadanna viadanna left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to go 👍

  • I tested this locally on my devstack.
  • I read through the code.
  • I checked for accessibility issues.
  • Includes documentation.

Comment thread openedx/core/lib/api/utils.py Outdated
Comment thread common/lib/xmodule/xmodule/x_module.py Outdated
An API for returning a css class identifying this module in the context of an icon.
It can be overridden by setting `GET_UNIT_ICON_IMPL` to an alternative implementation.
"""
return self.get_icon_class()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is defined on XModuleMixin, it will only apply to XModule instances, not XBlock ones, which is the newer class. Since this is where get_icon_class is defined too, that's probably fine, but I don't think this needs to be an XModuleMixin method at all... I think it could just be a top-level method in some runtime/xblock utils file, e.g.

@pluggable_override('GET_UNIT_ICON_IMPL')
def get_icon_for_block(block):
    return block.get_icon_class()

No need to change now, I'm not an official reviewer here, just pointing out options.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering about the correct place for this, but wasn't sure how this could be applied to XBlock, as it doesn't have a method for getting an icon. Should we just raise NotImplementedError when we don't find block.get_icon_class method?

@bradenmacdonald bradenmacdonald Sep 14, 2020

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was wondering about the correct place for this

I think it should be a top level function in xblock_utils/__init__.py. See my example that I'm replying to here.

Should we just raise NotImplementedError when we don't find block.get_icon_class method?

Return 'other' if it doesn't have a get_icon_class method; that's what get_icon_class does if it isn't overridden anyways.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, I'll move this.

Comment thread common/lib/xmodule/xmodule/modulestore/inheritance.py Outdated
@Agrendalath

Copy link
Copy Markdown
Member Author

@bradenmacdonald, thank you for your review! And sorry for addressing it late, I missed this email.

@Agrendalath

Copy link
Copy Markdown
Member Author

@natabene, this is ready for the review.

@natabene

Copy link
Copy Markdown
Contributor

@marcotuts Is this something you want to review before it moves to engineering?

@openedx-webhooks openedx-webhooks added product review PR requires product review before merging and removed waiting on author PR author needs to resolve review requests, answer questions, fix tests, etc. labels Sep 17, 2019
Comment thread openedx/core/lib/api/utils.py Outdated
mod = import_module(module)
func = getattr(mod, function)
return func(*args, **kwargs)
prev_fn = f # The base method in `edx-platform`.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might need to be partial(f, *args, **kwargs) because it becomes the prev_fn arg later, and the other prev_fn args already have the parameters applied?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point. Thank you for catching this!

@Agrendalath

Copy link
Copy Markdown
Member Author

@marcotuts, @natabene, any news on this?

@natabene

natabene commented Oct 8, 2019

Copy link
Copy Markdown
Contributor

@Agrendalath Sorry, no news yet.

@openedx-webhooks

Copy link
Copy Markdown

@Agrendalath Even though your pull request wasn’t merged, please take a moment to answer a two question survey so we can improve your experience in the future.

@marcotuts

marcotuts commented Feb 12, 2020

Copy link
Copy Markdown
Contributor

@ormsbee - This is ok to move to engineering review.

@Agrendalath - One question I have is that this seems like a large change to edx-platform for this plugin, is this largely a file relocation change, or what makes the change seem (at a glance) as large out of curiosity? Thanks!

@Agrendalath

Copy link
Copy Markdown
Member Author

@marcotuts, we divided monolithic cms/static/js/views/modals/course_outline_modals.js into smaller chunks to be able to override specific parts with a theme. This modular approach makes the theme much easier to maintain.

Btw. does the new courseware experience include these icons or is the navigation part altered in some way?

@bradenmacdonald

Copy link
Copy Markdown
Contributor

@marcotuts Does the new courseware experience include these icons?

Screen Shot 2020-02-29 at 4 14 12 PM

@marcotuts

marcotuts commented Mar 1, 2020

Copy link
Copy Markdown
Contributor

@bradenmacdonald, @Agrendalath - The icons are used in the new learning sequence bar / MFE: https://github.com/edx/frontend-app-learning

Note: We haven not yet release an initial version of this to production on edX.org, still in early testing, but included link as FYI for MFE focused on the course learner experience

@bradenmacdonald

Copy link
Copy Markdown
Contributor

@natabene Per @marcotuts's comment above (thanks!), could you please update this to "Engineering Review"? I think the status got lost when we mistakenly closed and re-opened the PR.

This is ok to move to engineering review.

@natabene

Copy link
Copy Markdown
Contributor

@bradenmacdonald The status is currently set to "Awaiting prioritization" and will be changed to "Engineering review" once we start reviewing it.

@bradenmacdonald

Copy link
Copy Markdown
Contributor

@Agrendalath Since the current courseware code (that you've modified here) will eventually be replaced by https://github.com/edx/frontend-app-learning , I think it might make sense to rebase this PR and strip out all the JavaScript/frontend changes, then test it with the frontend-app-learning MFE. That will make it easier to review and forwards-compatible.

Also I think it's worth calling more attention to the fact that this introduces a generic decorator for overriding any python function and as such provides a new model for platform extensibility - @natabene could we get some light engineering feedback on that approach soon?

@Agrendalath

Copy link
Copy Markdown
Member Author

@bradenmacdonald, sure, I'll set aside some time for the next sprint to change this.

Comment thread requirements/edx/testing.txt Outdated
@natabene

Copy link
Copy Markdown
Contributor

@Agrendalath Is this good to review now? openedx/edx-django-utils#64 has been merged

@Agrendalath

Copy link
Copy Markdown
Member Author

@natabene, yes, this is ready for review. We still need to push the new version of edx/edx-django-utils to PyPi (cf. my last comment on openedx/edx-django-utils#109), but this is not a blocker for reviewing this.

@natabene

Copy link
Copy Markdown
Contributor

@bradenmacdonald Do you still want to review this as a Core Committer?

@bradenmacdonald

Copy link
Copy Markdown
Contributor

@natabene Yes, I'm hoping to get to it soon. Thanks!

@bradenmacdonald bradenmacdonald left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks great, thanks!

This is a conditional approval; before we merge, please:

  • Get the version bump of edx-django-utils completed, and rebase this
  • Squash down to a single commit following conventional commits
  • I tested this: on my devstack, as described
  • I read through the code
  • I checked for accessibility issues
  • Includes documentation

Comment thread common/lib/xmodule/xmodule/seq_module.py Outdated
@Agrendalath
Agrendalath force-pushed the agrendalath/custom-icons branch 2 times, most recently from 67dd0f3 to bfef952 Compare April 2, 2021 12:53
@bradenmacdonald

Copy link
Copy Markdown
Contributor

following conventional commits

Don't forget this part ;)

@Agrendalath
Agrendalath force-pushed the agrendalath/custom-icons branch from bfef952 to 01cc05a Compare April 3, 2021 11:45
This:
1. Introduces a new override using the `pluggable_override` decorator. It is now possible to specify a custom way of getting XBlock's icon by defining `GET_UNIT_ICON_IMPL` in settings.
2. Introduces a way to add custom `XBLOCK_MIXINS` by defining `XBLOCK_EXTRA_MIXINS` in settings. This allows, e.g. to add new fields to XBlocks.
@Agrendalath
Agrendalath force-pushed the agrendalath/custom-icons branch from 01cc05a to c4c7197 Compare April 3, 2021 11:48
@edx-status-bot

Copy link
Copy Markdown

Your PR has finished running tests. There were no failures.

@kdmccormick
kdmccormick merged commit bc1e9af into openedx:master Apr 7, 2021
@openedx-webhooks

Copy link
Copy Markdown

@Agrendalath 🎉 Your pull request was merged!

Please take a moment to answer a two question survey so we can improve your experience in the future.

@kdmccormick

Copy link
Copy Markdown
Member

Thanks Braden and @Agrendalath . FYI, when squashing, I hard-wrapped your commit message body at ~80 chars. Git doesn't auto-wrap messages very well :)

@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production.

@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the production environment.

@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the staging environment in preparation for a release to production.

@edx-pipeline-bot

Copy link
Copy Markdown
Contributor

EdX Release Notice: This PR has been deployed to the production environment.

@Agrendalath
Agrendalath deleted the agrendalath/custom-icons branch April 7, 2021 18:42
@Agrendalath
Agrendalath restored the agrendalath/custom-icons branch April 8, 2021 18:34
@Agrendalath
Agrendalath deleted the agrendalath/custom-icons branch April 8, 2021 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.