-
Notifications
You must be signed in to change notification settings - Fork 10
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
Unite Template
and Renderer
classes
#94
Conversation
4ebfa41
to
8dfc4d8
Compare
The renderers are going to become part of the `Template` class, so there are going to be more tests of the various types of template than just the ones in this file. But I don’t wanna merge them all into one file because they’ll be testing different things, and it could get very long.
Just so it doesn’t get lost amongst all the other template stuff.
8dfc4d8
to
dafc322
Compare
This is a big refactor. It’s addressing three issues which were making the existing code bloated and overly complicated: 1. The interaction between the `Template` and `Renderer` classes was still weird, because an instance of `Renderer` had effectively become a method of a `Template` instance 2. The `Renderer` classes themselves weren’t really proper classes, they were bsically just functions that took a template and turned it into a string, but architected in a slightly odd way. There are people who consider a class that only has `__init__` and `__call__` methods an anti-pattern [1] 3. There were methods on the `Template` class (eg `content_count`) which were very specific to one kind of template (eg a text message). This commit makes two main changes to address these issues: 1. Makes `Template` into an abstract-ish base class, and makes the various `Renderer`s into `Template`s which inherit from the base template class (ie `HTMLEmailTemplate` instead of a renderer called `HTMLEmail`). 2. Moves the functionality of the renderers to `__str__` methods on template instances. This is a better model of what they do (turn templates into strings). 3. Methods that are only relevant to one type of template (eg text messages) now live only on that type of template. --- 1. Stop writing classes – Jack Diedrich: https://www.youtube.com/watch?v=o9pEzgHorH0
Brings in: - [ ] alphagov/notifications-utils#94
Brings in: - [ ] alphagov/notifications-utils#94
It’s really ugly having to do this sort of thing all over the API: ```python subject=str(Field(plain_text_email.subject, notification.personalisation)) ``` But it doesn’t really belong in the base `Template` class because not all templates have subjects. So this commit re-adds subjects (and the highlighting/replacing thereof) to those templates which do have subject lines. So the API code can just change to: ```python subject=template.subject ```
Includes: - [ ] alphagov/notifications-utils#94 (breaking changes which are responsible for all the changes to the API in this PR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(unrelated to current PR but there's some unreachable code in recipients.py#L269)
tested locally with admin and api checked out to respective PRs. seems mostly reasonable. code wise seems fine but there's too much code change here for me to critique layout without getting a headache ;)
but it doesn't honour sms placeholders exceeding max length and firetext throws a 400 at us
raise TypeError("The template needs to have a template type of 'sms'") | ||
return get_sms_fragment_count(self.content_count) | ||
def content_count(self): | ||
return len(str(self).encode(self.encoding)) | ||
|
||
@property | ||
def content_too_long(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused property? it certainly errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the API was doing this comparison itself. Removed in: 7997fc7
'subject': self.subject, | ||
'from_name': self.from_name, | ||
'from_address': self.from_address, | ||
'recipient': Field("((email address))", template.get('values', {}), with_brackets=False), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
think this should be self._template
? it's currently crashing when i try and send an email on admin app, so make sure there's a test for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
self.values
. I think I’d fixed this already and squashed it out but not pushed it or something ¯_(ツ)_/¯
Includes: - [ ] alphagov/notifications-utils#94 (breaking changes which are responsible for all the changes to the API in this PR)
This method was actually broken by recent changes, and the API wasn’t using it anyway – it was just doing the comparison itself. This requires a slight change to `RecipientCSV` to also do the comparison itself.
Significant, breaking changes: - changes the interface to the `Template` class, including removal of the `drop_values` argument for all template types - removes all `Renderer` classes and moves them to methods of subclasses of the `Template` class
dafc322
to
0a781c2
Compare
Addresses unreachable code in a separate PR: #101 |
Brings in: - [ ] alphagov/notifications-utils#94
Includes: - [ ] alphagov/notifications-utils#94 (breaking changes which are responsible for all the changes to the API in this PR)
Includes: - [x] alphagov/notifications-utils#94 (breaking changes which are responsible for all the changes to the API in this PR) The test for `get_sms_fragment_count` has been removed because this method is already tested in utils here: https://github.com/alphagov/notifications-utils/blob/ac20f7e99ece4935fccf39ed9d5c0fb40e45bfbc/tests/test_base_template.py#L140-L159
Brings in: - [ ] alphagov/notifications-utils#94
Brings in: - [ ] alphagov/notifications-utils#94
Brings in: - [ ] alphagov/notifications-utils#94
So this is the work that I wanted to do as part of #84 but wasn’t sure whether it was worth the effort. But @leohemsted’s comments on that PR got me thinking again, and I had 2 uninterrupted hours on the train this morning, so here we are.
This is a big refactor. It’s addressing three issues which were making the existing code bloated and overly complicated:
The interaction between the
Template
andRenderer
classes was still weird, because an instance ofRenderer
had effectively become a method of aTemplate
instanceThe
Renderer
classes themselves weren’t really proper classes, they were basically just functions that took a template and turned it into a string, but architected in a slightly odd way. There are people who consider a class that only has__init__
and__call__
methods an anti-pattern (see Jack Diedrich’s talk Stop writing classesThere were methods on the
Template
class (egcontent_count
) which were very specific to one kind of template (eg a text message).This commit makes three main changes to address these issues:
Makes
Template
into an abstract-ish base class, and makes the variousRenderer
s intoTemplate
s which inherit from the base template class (ieHTMLEmailTemplate
instead of a renderer calledHTMLEmail
).Moves the functionality of the renderers to
__str__
methods on template instances. This is a better model of what they do (turn templates into strings).Methods that are only relevant to one type of template (eg text messages) now live only on that type of template.
There is one thing that’s still slightly weird about this. Service-level things on a template (eg the text message sender name) aren’t set through an__init__
method any more because there’s no appropriate place for one to exist.Instead they are set directly on the instance (egtemplate.sms_sender = 'Service name'
). This means doing some slightly funny jiggery pokery around default and required ‘arguments’, whichwould be more intuitive with an
__init__
. But I think the tradeoff is worth it for the simpler code elsewhere.super()
considered super!Also, add subject property back onto certain templates
It’s really ugly having to do this sort of thing all over the API:
But it doesn’t really belong in the base
Template
class because not all templates have subjects.So this commit re-adds subjects (and the highlighting/replacing thereof) to those templates which do have subject lines.
So the API code can just change to: