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

DEV: Migrate social_links theme setting to new objects setting type #47

Merged
merged 1 commit into from
May 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions javascripts/discourse/components/custom-footer.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@
</div>

<div class="social">
{{#each this.socialLinks as |link|}}
{{#each (theme-setting "social_links") as |link|}}
<a
class="social-link"
data-easyfooter-social-link={{link.dataName}}
data-easyfooter-social-link={{dasherize link.text}}
title={{link.title}}
target={{link.target}}
href={{link.href}}
href={{link.url}}
>
{{d-icon link.icon}}
{{d-icon link.icon_name}}
</a>
{{/each}}
</div>
Expand Down
23 changes: 0 additions & 23 deletions javascripts/discourse/components/custom-footer.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,6 @@
import Component from "@glimmer/component";
import { dasherize } from "@ember/string";

export default class extends Component {
mainHeading = settings.heading;
blurb = settings.blurb;

socialLinks = settings.social_links
.split("|")
.filter(Boolean)
.map((link) => {
const fragments = link.split(",").map((fragment) => fragment.trim());
const text = fragments[0];
const dataName = dasherize(text);
const title = fragments[1];
const href = fragments[2];
const target = fragments[3] === "blank" ? "_blank" : "";
const icon = fragments[4].toLowerCase();

return {
text,
dataName,
title,
href,
target,
icon,
};
});
}
20 changes: 19 additions & 1 deletion locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,25 @@ en:
description: The target attribute of the link

social_links:
description: "Enter the social links you'd like to add to the footer in this format:<br> provider, title, URL, target<br><b>Provider:</b> is the name of the provider like Facebook or Twitter<br><b>Title:</b> The text that shows when the link is hovered<br><b>URL:</b> The path you'd like the link to have<br><b>Target:</b> Use blank to open the link in a new tab and use self to open it in the same tab<br><b>Icon:</b> use a FontAwesome5 icon name (brand icons need a 'fab-' prefix)."
description: "Social links you'd like to add to the footer"
schema:
properties:
text:
label: Text
description: Text to be displayed for the link
title:
label: Title
description: The title attribute of the link
url:
label: URL
description: The URL the link points to
target:
label: Target
description: The target attribute of the link
icon_name:
label: Icon Name
description: FontAwesome5 icon name (brand icons need a 'fab-' prefix)

show_footer_on_login_required_page:
description: "Check this setting if you want the footer to be displayed on the login-required page (only applies if your site is private)"
svg_icons:
Expand Down
47 changes: 47 additions & 0 deletions migrations/settings/0004-migrate-social-links-setting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
export default function migrate(settings, helpers) {
const oldSocialLinks = settings.get("social_links");

if (oldSocialLinks) {
const newSocialLinks = [];

oldSocialLinks.split("|").forEach((oldSocialLink) => {
const [linkText, linkTitle, linkUrl, linkTarget, linkIcon] = oldSocialLink
.split(",")
.map((value) => value.trim());

if (linkText) {
const newLink = {
text: linkText,
};

if (linkTitle) {
newLink.title = linkTitle.substring(0, 1000);
}

if (linkUrl && helpers.isValidUrl(linkUrl) && linkUrl.length <= 2048) {
newLink.url = linkUrl;
} else {
newLink.url = "#";
}

if (linkTarget === "self") {
newLink.target = "_self";
} else {
newLink.target = "_blank";
}

if (linkIcon && linkIcon.length <= 200) {
newLink.icon_name = linkIcon.toLowerCase();
}

newSocialLinks.push(newLink);
}
});

settings.set("social_links", newSocialLinks);
} else if (oldSocialLinks?.trim() === "") {
settings.set("social_links", []);
}

return settings;
}
55 changes: 52 additions & 3 deletions settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,58 @@ small_links:
- _top

social_links:
type: list
list_type: simple
default: "Facebook, Join us on Facebook, #, blank,fab-facebook|Twitter, show some love on Twitter, #, blank,fab-twitter| Youtube, Check out our latest videos on Youtube, #, blank,fab-youtube"
type: objects
default:
- text: Facebook
title: Join us on Facebook
url: "#"
target: _blank
icon_name: fab-facebook
- text: Twitter
title: Show some love on Twitter
url: "#"
target: _blank
icon_name: fab-twitter
- text: Youtube
title: Check out our latest videos on Youtube
url: "#"
target: _blank
icon_name: fab-youtube
schema:
name: social link
identifier: text
properties:
text:
type: string
required: true
validations:
min_length: 1
max_length: 1000
title:
type: string
validations:
min_length: 1
max_length: 1000
url:
type: string
required: true
validations:
min_length: 1
max_length: 2048
url: true
target:
type: string
default: _blank
choices:
- _blank
- _self
- _parent
- _top
icon_name:
type: string
validations:
min_length: 1
max_length: 200

show_footer_on_login_required_page:
default: true
Expand Down
212 changes: 212 additions & 0 deletions spec/migrations/0004_migrate_social_links_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
# frozen_string_literal: true

RSpec.describe "0004-migrate-social-links-setting migration" do
let!(:theme) { upload_theme_component }

it "should handle an empty string for old setting" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: " ",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq([])
end

it "does not migrate links which do not have a text property" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: " ,some title, /some/url",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq([])
end

it "should migrate title property correctly if previous title property is valid" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: "Some Text, Some Title",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[{ "text" => "Some Text", "title" => "Some Title", "url" => "#", "target" => "_blank" }],
)
end

it "should truncate title property to 1000 chars if previous title property is more than 1000 chars" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: "Some Text, #{"a" * 1001}",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[{ "text" => "Some Text", "title" => "#{"a" * 1000}", "url" => "#", "target" => "_blank" }],
)
end

it "should set URL property to `#` if previous URL property is invalid, empty or is more than 2048 chars" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value:
"Some Text, Some Title|Some Text 2, Some Title 2, not a URL|Some Text 3, Some Title 3, #{"a" * 2049}",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[
{ "text" => "Some Text", "title" => "Some Title", "url" => "#", "target" => "_blank" },
{ "text" => "Some Text 2", "title" => "Some Title 2", "url" => "#", "target" => "_blank" },
{ "text" => "Some Text 3", "title" => "Some Title 3", "url" => "#", "target" => "_blank" },
],
)
end

it "should migrate URL property correctly if previous URL property is valid" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: "Some Text, Some Title, /some/url|Some Text 2, Some Title 2, http://example.com",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[
{
"text" => "Some Text",
"title" => "Some Title",
"url" => "/some/url",
"target" => "_blank",
},
{
"text" => "Some Text 2",
"title" => "Some Title 2",
"url" => "http://example.com",
"target" => "_blank",
},
],
)
end

it "sets target property to `_self` if previous target property is `self`" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: "Some Text, Some Title, /some/url, self",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[
{
"text" => "Some Text",
"title" => "Some Title",
"url" => "/some/url",
"target" => "_self",
},
],
)
end

it "does not set target property if previous target property is invalid or empty" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value:
"Some Text, Some Title, /some/url|Some Text 2, Some Title 2, http://example.com, not a target",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[
{
"text" => "Some Text",
"title" => "Some Title",
"url" => "/some/url",
"target" => "_blank",
},
{
"text" => "Some Text 2",
"title" => "Some Title 2",
"url" => "http://example.com",
"target" => "_blank",
},
],
)
end

it "does not set icon_name property if previous icon_name property is empty or more than 200 chars" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value:
"Some Text, Some Title, /some/url, self|Some Text 2, Some Title 2, http://example.com, self, #{"a" * 201}",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[
{
"text" => "Some Text",
"title" => "Some Title",
"url" => "/some/url",
"target" => "_self",
},
{
"text" => "Some Text 2",
"title" => "Some Title 2",
"url" => "http://example.com",
"target" => "_self",
},
],
)
end

it "sets the icon_name property correctly if previous icon_name property is present" do
theme.theme_settings.create!(
name: "social_links",
theme:,
data_type: ThemeSetting.types[:string],
value: "Some Text, Some Title, /some/url, self, some-icon",
)

run_theme_migration(theme, "0004-migrate-social-links-setting")

expect(theme.settings[:social_links].value).to eq(
[
{
"text" => "Some Text",
"title" => "Some Title",
"url" => "/some/url",
"target" => "_self",
"icon_name" => "some-icon",
},
],
)
end
end
Loading
Loading