-
\ No newline at end of file
diff --git a/dokka-templates/includes/header.ftl b/dokka-templates/includes/header.ftl
index 0d6f0911815..91b5a1a1107 100644
--- a/dokka-templates/includes/header.ftl
+++ b/dokka-templates/includes/header.ftl
@@ -1,24 +1,28 @@
<#import "source_set_selector.ftl" as source_set_selector>
<#macro display>
-
-
-
+
+
+
search in API
+
+
#macro>
\ No newline at end of file
diff --git a/dokka-templates/includes/page_metadata.ftl b/dokka-templates/includes/page_metadata.ftl
index 89b3ddba24f..a8ac01d576a 100644
--- a/dokka-templates/includes/page_metadata.ftl
+++ b/dokka-templates/includes/page_metadata.ftl
@@ -3,4 +3,4 @@
<@template_cmd name="pathToRoot">
@template_cmd>
-#macro>
\ No newline at end of file
+#macro>
diff --git a/dokka-templates/includes/source_set_selector.ftl b/dokka-templates/includes/source_set_selector.ftl
index 13650ee59c5..40329528ef0 100644
--- a/dokka-templates/includes/source_set_selector.ftl
+++ b/dokka-templates/includes/source_set_selector.ftl
@@ -1,5 +1,5 @@
<#macro display>
- <#if sourceSets??>
+ <#if sourceSets?has_content>
<#list sourceSets as ss>
diff --git a/package.json b/package.json
index f39175142b4..580fd811578 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,7 @@
"inter-ui": "3.19.3",
"iso-639-1": "2.1.13",
"jquery": "3.5.0",
+ "key-value-parser": "0.2.0",
"kotlin-playground": "^1.27.0",
"mini-css-extract-plugin": "1.6.1",
"mini-svg-data-uri": "1.1.3",
@@ -70,6 +71,7 @@
"svgo-loader": "3.0.0",
"tslib": "2.2.0",
"url-loader": "^4.0.0",
+ "use-match-media-hook": "1.0.1",
"validator": "13.7.0",
"webpack": "5.76.0",
"webpack-cli": "4.7.2",
diff --git a/scripts/dokka/generate-templates.js b/scripts/dokka/generate-templates.js
index 5e7dd319bbb..9677abc1c88 100644
--- a/scripts/dokka/generate-templates.js
+++ b/scripts/dokka/generate-templates.js
@@ -1,52 +1,82 @@
-const fs = require('fs');
-const path = require('path');
-const {execSync} = require('child_process');
+const {join} = require('path');
+const {execFileSync, execSync, spawnSync} = require('child_process');
+const {readdirSync, readFileSync, writeFileSync} = require('fs');
+const KeyValueParser = require('key-value-parser');
console.info(`Start generating Dokka's templates`);
walkTroughTemplates('dokka-templates');
+function isFreemakerTemplate(item) {
+ return item.isFile() && item.name.endsWith('.ftl');
+}
+
+function replaceEnv(value) {
+ let matched;
+
+ while (matched = value.match(/\$\{process\.env\.([^}]+)\}/)) {
+ const { 0: token, 1: variable, index } = matched;
+ const envValue = process.env[variable];
+ value = value.substring(0, index) + envValue + value.substring(index + token.length);
+ }
+
+ return value;
+}
+
+function normalizeProps(props) {
+ for (const [key, value] of Object.entries(props)) {
+ props[key] = replaceEnv(value);
+ }
+ return props;
+}
+
+function parsePropsString([definition, _, componentName, propsString]) {
+ return new Promise((resolve, reject) => {
+ new KeyValueParser(propsString || '', { async: true, quoted: '\"' })
+ .on('end', props => resolve([definition, componentName, normalizeProps(props)]))
+ .on('error', err => reject(err));
+ });
+}
+
+function parseFreemakerContent(originalContent) {
+ /* parse to [ fullEntry, componentName, propsString ] */
+ const parseRegex = /(\{%\s*ktl_component\s+"(\w+)"\s*(\s[^%]+)?%})/g;
+
+ return Promise.all([...originalContent.matchAll(parseRegex)].map(parsePropsString))
+ .then(entries => entries
+ .reduce((text, [definition, componentName, props]) => {
+ const rendered = compileComponent(componentName, props);
+ console.log(rendered);
+ return text.replace(definition, rendered);
+ }, originalContent)
+ )
+}
+
/**
- * Use the next example to define ktl component in ftl templates: {% ktl_component "COMPONENT_NAME" %}
+ * Use the next example to define ktl component in ftl templates: {% ktl_component "COMPONENT_NAME" [PROPS] %}
*/
function walkTroughTemplates(filePath) {
- fs.readdirSync(filePath, {withFileTypes: true}).forEach(item => {
- const currentPath = path.join(filePath, item.name);
-
- if (item.isDirectory()) {
- walkTroughTemplates(currentPath);
- } else if (item.isFile() && item.name.endsWith('.ftl')) {
- const fileContent = fs.readFileSync(currentPath).toString();
- let updatedContent = fileContent;
- const pattern = /\{%\s?ktl_component\s?["'](\w+)['"]\s?%}/g;
- const results = [...updatedContent.matchAll(pattern)];
-
- results.forEach(result => {
- const componentName = result[1];
- console.info(`Generating ${componentName}...`);
- const componentTemplate = compileComponent(componentName);
- console.log(componentTemplate);
- const componentPattern = new RegExp(`{%\\s?ktl_component\\s?["']${componentName}['"]\\s?%}`, 'g');
-
- updatedContent = updatedContent.replace(componentPattern, componentTemplate);
-
- console.info(`Generating ${componentName} is completed`);
- });
-
- if (fileContent !== updatedContent) {
- console.info(`Updating ${currentPath} file`);
- fs.writeFileSync(currentPath, updatedContent);
- console.info(`${currentPath} file is updated`);
- }
- }
- });
+ readdirSync(filePath, {withFileTypes: true}).forEach(item => {
+ const currentPath = join(filePath, item.name);
+
+ if (item.isDirectory()) walkTroughTemplates(currentPath);
+ else if (isFreemakerTemplate(item)) {
+ const originalContent = readFileSync(currentPath).toString('UTF-8');
+
+ parseFreemakerContent(originalContent).then(newContent => {
+ if (newContent !== originalContent) {
+ console.info(`Updating ${currentPath} file`);
+ writeFileSync(currentPath, newContent);
+ console.info(`${currentPath} file is updated`);
+ }
+ });
+ }
+ });
}
-function compileComponent(name) {
- const stdout = execSync(`node scripts/react-renderer/compile.js ${name} {} dokka`);
+function compileComponent(name, props) {
+ const propsString = JSON.stringify(props);
+ const stdout = execFileSync('node', ['scripts/react-renderer/compile.js', name, propsString, 'dokka'], {encoding: 'utf-8'});
- return `
-
- ${stdout}
- `
+ return ` ${stdout}`;
}
diff --git a/static/js/ktl-component/ktl-helpers.js b/static/js/ktl-component/ktl-helpers.js
index 2506bc9b4ca..2595c74f6ed 100644
--- a/static/js/ktl-component/ktl-helpers.js
+++ b/static/js/ktl-component/ktl-helpers.js
@@ -15,12 +15,7 @@ export function ktlHelpers() {
if (nodeValue.startsWith(comment)) {
const { name, props } = JSON.parse(nodeValue.substring(comment.length));
-
- result.push({
- name: name,
- props: props,
- node: currentNode
- });
+ result.push({ name, props, node: currentNode });
}
}
}
@@ -32,4 +27,24 @@ export function initComponent(node, Component, props) {
const fake_node = document.createElement('div');
hydrate(createElement(Component, props), fake_node);
node.replaceWith(fake_node);
-}
\ No newline at end of file
+}
+
+export function replaceByComponent(node, Component, props) {
+ const parentNode = node.parentNode;
+ const fakeNode = document.createElement('div');
+
+ hydrate(createElement(Component, props), fakeNode);
+
+ let renderedNode = fakeNode.lastChild;
+
+ if (fakeNode.children.length === 1) {
+ node.replaceWith(renderedNode);
+ return;
+ }
+
+ do {
+ parentNode.insertBefore(node, renderedNode);
+ } while (renderedNode = renderedNode.previousSibling)
+
+ parentNode.removeChild(node);
+}
diff --git a/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.jsx b/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.jsx
index 22fd8f2a316..5f4524680e7 100644
--- a/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.jsx
+++ b/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.jsx
@@ -15,7 +15,7 @@ export const TeachCtaBlock = () => {
-
+
diff --git a/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.scss b/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.scss
index 54256cc8370..721253832cf 100644
--- a/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.scss
+++ b/static/js/ktl-component/teach/components/teach-cta-block/teach-cta-block.scss
@@ -6,6 +6,11 @@
}
@media (max-width: 768px) {
+ .teach-cta-block-buttons {
+ display: flex;
+ flex-direction: column;
+ }
+
.teach-cta-block-button {
font-size: 16px;
padding: 8px 24px;
diff --git a/static/js/ktl-component/teach/components/teach-launch-course/index.js b/static/js/ktl-component/teach/components/teach-launch-course/index.js
new file mode 100644
index 00000000000..80579eebe71
--- /dev/null
+++ b/static/js/ktl-component/teach/components/teach-launch-course/index.js
@@ -0,0 +1,3 @@
+import {TeachLaunchCourse} from "./teach-launch-course.jsx";
+
+export {TeachLaunchCourse};
\ No newline at end of file
diff --git a/static/js/ktl-component/teach/components/teach-launch-course/teach-launch-course.jsx b/static/js/ktl-component/teach/components/teach-launch-course/teach-launch-course.jsx
new file mode 100644
index 00000000000..bb68bb49c24
--- /dev/null
+++ b/static/js/ktl-component/teach/components/teach-launch-course/teach-launch-course.jsx
@@ -0,0 +1,166 @@
+import React from 'react';
+
+import { useTextStyles } from '@rescui/typography';
+import './teach-launch-course.scss';
+
+import Button from '@rescui/button';
+
+import classNames from 'classnames';
+
+export const TeachLaunchCourse = () => {
+ const textCn = useTextStyles();
+
+ return (
+
+
+ The Programming in Kotlin course is a comprehensive toolkit for teaching Kotlin and can be easily
+ customized to align with specific educational needs. The course comes with slides, lecture notes, and
+ assessment resources.
+
+
+
+
+
+
+
+
+
+
+
Assessment resources
+
+
+
+
+ );
+};
diff --git a/static/js/ktl-component/teach/components/teach-launch-course/teach-launch-course.scss b/static/js/ktl-component/teach/components/teach-launch-course/teach-launch-course.scss
new file mode 100644
index 00000000000..4502789f1f9
--- /dev/null
+++ b/static/js/ktl-component/teach/components/teach-launch-course/teach-launch-course.scss
@@ -0,0 +1,76 @@
+.teach-launch-course__links-block {
+ margin-top: 32px;
+}
+
+.teach-launch-course__list {
+ li {
+ margin-bottom: 8px;
+ }
+}
+
+.teach-launch-course__button-wrap {
+ margin-top: 32px;
+ display: flex;
+ justify-content: stretch;
+}
+
+@media (max-width: 767px) {
+ .teach-launch-course__button {
+ font-size: 16px;
+ padding: 8px 24px;
+ }
+}
+
+@media (min-width: 768px) {
+ .teach-launch-course__list_large {
+ column-count: 2;
+ }
+}
+
+@media (min-width: 1000px) {
+ .teach-launch-course {
+ display: grid;
+ grid-template-rows: auto;
+ grid-template-areas:
+ "content content content"
+ "column1 column1 column3";
+ border-bottom: 1px solid #d4d4d5;
+ padding-bottom: 48px;
+
+ &__text {
+ grid-area: content;
+ }
+
+ &__links-block_first {
+ grid-area: column1;
+ }
+
+ &__links-block_second {
+ grid-area: column3;
+ }
+ }
+}
+
+@media (min-width: 1280px) {
+ .teach-launch-course {
+ grid-template-columns: 33.33% 2fr 1fr;
+ grid-template-areas:
+ "content column1 column2";
+
+ &__text {
+ padding-right: 64px;
+ }
+
+ &__links-block {
+ margin-top: 0;
+ }
+
+ &__links-block_first {
+ grid-area: column1;
+ }
+
+ &__links-block_second {
+ grid-area: column2;
+ }
+ }
+}
diff --git a/static/js/ktl-component/teach/index.jsx b/static/js/ktl-component/teach/index.jsx
index 4475db0bad8..b5ff946fb1d 100644
--- a/static/js/ktl-component/teach/index.jsx
+++ b/static/js/ktl-component/teach/index.jsx
@@ -16,463 +16,475 @@ import {SubscriptionForm} from './components/subscription-form';
import {TeachMap} from './components/teach-map/teach-map.jsx';
import {SlackIcon} from "@rescui/icons";
import Button from "@rescui/button";
+import { TeachLaunchCourse } from "./components/teach-launch-course";
+
+import { useTextStyles } from '@rescui/typography';
const Teach = (props) => {
const {countriesCount, universitiesCount, path} = props;
+ const textCn = useTextStyles();
return (
-
-
-
-
- Kotlin 适合教授各种计算机科学课程
-
-
-
- }
- href="https://surveys.jetbrains.com/s3/kotlin-slack-signup-educators"
- target="_blank" rel="noopener" className="teach-cta-block-button">Join Educators Сommunity
-
-
-
-
-
-
-
-
-

+
+
+
+ Teach Computer Science with Kotlin
+
+
+
+
+ }
+ href="https://surveys.jetbrains.com/s3/kotlin-slack-signup-educators"
+ target="_blank"
+ rel="noopener"
+ className="teach-cta-block-button"
+ >
+ Join Educators Сommunity
+
+
+
-
-
Multiplatform
-
-
- The first-choice language for Android development, Kotlin is also being adopted for teaching
- multiplatform
- development for mobile, web, server-side programming, data science, and other computer science topics.
-
-
-
-
-
-
-
-
-

-
+
+
+
+
+

+
+
+
+
Academically recognized
+
+
+ Over 300 of the world’s top universities include Kotlin in various computer science courses (as of June 2023).
+
+
+
+
-
-
学术认可
+
+
+
+

+
+
+
+
Language of the industry
+
+
+ Kotlin is used by top companies such as Google, Amazon, Twitter, Reddit, Netflix,
+ Uber, Slack, just to name a few.
+
+
+
+
-
- 在 2021 年《泰晤士报全世界高等教育排名》排名前 100 的大学中,有 25 所大学将 Kotlin
- 纳入课程。
-
-
-
-
-
-
-
-
-

+
+
+
+

+
+
+
+
Multiplatform
+
+
+ Kotlin is a top choice for teaching Android development. It is also being adopted for
+ teaching multiplatform development, web, server-side programming, data science, and
+ other computer science topics.
+
+
+
+
-
-
Language of the industry
-
-
- Kotlin is used by top companies such as Google, Twitter, Reddit, Netflix, Uber, BMW, Coursera, Slack,
- and
- Trello, just to name a few.
-
-
-
-
-
-
-
-
- }
- href="https://surveys.jetbrains.com/s3/kotlin-slack-signup-educators"
- target="_blank" rel="noopener" className="teach-cta-block-button">Join Educators Сommunity
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Explore our interactive map with links to university courses that
include Kotlin.
-
+
+
+ }
+ href="https://surveys.jetbrains.com/s3/kotlin-slack-signup-educators"
+ target="_blank"
+ rel="noopener"
+ className="teach-cta-block-button"
+ >
+ Join Educators Сommunity
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Explore our interactive map with links to university courses that
+
include Kotlin.
+
+
+
+
+ Kotlin is taught at {universitiesCount} universities
+
+
+
+
+
+
+
-
- Kotlin is taught at {universitiesCount} universities
-
+
+
+
+

+
+
+

+
+
+

+
+
+

+
+
+

+
+
+
-
-
-
-
-
-
-
-
-
-

-
-
-

-
-
-

-
-
-

+
+
+
+
+
+
+ To add your university’s Kotlin course to the map, contact us at
+ {' '}
+
+ education@kotlinlang.org.
+
+
We’ll send you a Kotlin T-shirt and stickers for your students.
+
+
+
+
+
+
+
+
+
-
-

+
+
+
+
+
+

+
+
+
+ -
+
入门
+
+
+
+ -
+
Tools
+
+
+
+ -
+
Online Courses
+
+
+
+ -
+
Kotlin Android 开发
+
+
+
+ -
+
Practice Kotlin
+
+
+
-
-
-
-
-
-
-
-
-
- If you would like to feature your university and Kotlin course, please get in touch with us at education@kotlinlang.org.
We’ll
- send a Kotlin T-shirt for you and stickers for your students.
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
- -
-
入门
-
-
-
- -
-
Study materials
-
-
-
- -
-
Tools
-
-
-
- -
-
Online Courses
-
-
-
- -
-
Kotlin Android 开发
-
- -
-
- 文档
-
-
- -
-
由 Google 的 Android 开发人员关系团队推荐:
+
+
+
+
+
+
-
-
-
-
-
-
-
Practice Kotlin by solving problems
-
-
-
-
-
- Slack
-
-
- The #education Slack channel is a place to meet fellow educators and the Kotlin team. We post news and
- announcements there, and you can ask your questions and share your teaching experience.
-
-
- Request to join
- ↗
-
-
-
-
-
-
Connect with us
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- )
- ;
+
+
+
+
+
+ );
}
export default Teach;
diff --git a/static/js/ktl-component/teach/style.scss b/static/js/ktl-component/teach/style.scss
index 318189d0e53..970333bd5de 100644
--- a/static/js/ktl-component/teach/style.scss
+++ b/static/js/ktl-component/teach/style.scss
@@ -25,6 +25,7 @@
display: grid;
grid-gap: 16px;
margin-bottom: 32px;
+ margin-top: 32px;
@media (min-width: 768px) {
display: none;
@@ -207,9 +208,29 @@
@media (min-width: 768px) {
grid-template-columns: repeat(3, 1fr);
grid-gap: 48px;
- }
- @media (min-width: 1200px) {
- grid-template-columns: repeat(4, 1fr);
+ grid-template-areas:
+ "left center1 right1"
+ "left center2 right2";
+
+ &__first-list {
+ grid-area: left;
+ }
+
+ &__second-list {
+ grid-area: center1;
+ }
+
+ &__third-list {
+ grid-area: center2;
+ }
+
+ &__fourth-list {
+ grid-area: right1;
+ }
+
+ &__fifth-list {
+ grid-area: right2;
+ }
}
}
diff --git a/static/js/ktl-component/why-teach/index.jsx b/static/js/ktl-component/why-teach/index.jsx
index 3a76eb053b7..8a6bb986aaa 100644
--- a/static/js/ktl-component/why-teach/index.jsx
+++ b/static/js/ktl-component/why-teach/index.jsx
@@ -32,17 +32,9 @@ export const WhyTeach = ({path}) => {
- 25 of the top 100 universities in the Times Higher Education World University Rankings 2021 include
- Kotlin in their courses. We know of 190 universities that teach Kotlin, which is almost twice as
- many as
- there were in 2020.
-
-
-
- Kotlin is used to teach a variety of topics, including object-oriented and functional programming,
- software engineering, introductory programming, mobile application development, concurrent
- programming,
- and scientific programming (Source: internal Teaching Kotlin Study).
+ We know of over 300 universities that teach Kotlin in a variety of subjects, including object-oriented
+ and functional programming, software development, introductory programming, mobile application development,
+ concurrent programming, scientific programming, and more (Source: internal Teaching Kotlin Study, June 2023).
{
-
25
+
32
- of the top 100 universities in the Times Higher Education World University Rankings 2021 include
+ of the top 100 universities in the Times Higher Education World University Rankings 2023 include
Kotlin
in
their courses.
@@ -79,29 +71,25 @@ export const WhyTeach = ({path}) => {
-
- Kotlin is used by top companies such as Google, Twitter, Reddit, Netflix, Uber, BMW, Coursera,
- Slack, and Trello, just to name a few.
+ Kotlin is used by top companies such as Google, Amazon, Twitter, Reddit, Netflix, Uber, Slack,
+ just to name a few.
-
- Kotlin has consistently ranked among the top 4 most-loved programming languages since 2018,
- according to the Stack
- Overflow Developer Surveys.
+ Teaching professional software engineering practices improves students’ employment prospects.
+ And knowing that Kotlin is a marketable skill, students tend to be more enthusiastic in studying it.
-
- Kotlin is one of the fastest-growing programming languages, ranking fourth in that category
- in GitHub’s 2019 State of
- the Octoverse
- survey.
+ One out of every two developers is planning to adopt a new language.
+ Kotlin is one of the three top choices for next languages.
+ The
+ State of Developer Ecosystem 2022
-
- Kotlin has the fastest growing language community. (SlashData's
- State of the Developer Nation 20th
- edition, Q1 2021)
+ In 2020, Kotlin became the 2nd most popular language on the JVM.
+ Snyk.io JVM Ecosystem Report 2020
+
@@ -111,14 +99,14 @@ export const WhyTeach = ({path}) => {
@@ -134,9 +122,8 @@ export const WhyTeach = ({path}) => {
- The first-choice language for Android development, Kotlin is also being adopted for teaching
- multiplatform development for mobile, web, server-side programming, data science, and other computer
- science topics.
+ Kotlin is a top choice for teaching Android development. It is also being adopted for teaching
+ multiplatform development, web, server-side programming, data science, and other computer science topics.
{
- Android development will become increasingly Kotlin-first.
+ The Kotlin Multiplatform Mobile and Compose Multiplatform frameworks
+ from JetBrains help developers share code between their Android and iOS apps.
+ These frameworks now offer experimental support for Kotlin compilation to WebAssembly.
- Google I/O 2019
+ Google for Developers blog, 2023
↗
-
-
-
- Easy to learn
-
-
-
-
-
-
- Kotlin has a soft learning curve and builds on the students' previous programming experience. It is
- simple to grasp for those with a Java or Python background.
-
-
-
-
-
-
-
88%
-
- of students give positive feedback about learning Kotlin
-
-
- (Source: internal Teaching Kotlin Study)
-
-
-
-
-
Interoperable
@@ -198,10 +157,8 @@ export const WhyTeach = ({path}) => {
Seamless interoperability with the JVM ecosystem means that Kotlin can rely on numerous existing
- libraries. Java programs can also call Kotlin code without any overhead. Our helpful Java-to-Kotlin
- converter makes it easy to migrate existing course materials. It also helps students quickly learn
- the
- syntax if they are already familiar with Java.
+ libraries. The Kotlin plugin bundles a Java to Kotlin converter (J2K) that automatically converts
+ Java files to Kotlin.
{
- Kotlin can also be compiled to JavaScript to run in the browser or on Node.js, or into a standalone
- native binary targeting any major operating system.
+ Kotlin can also be compiled into a standalone native binary targeting any major operating system.
-
-
- Prepares students for careers
-
-
-
-
-
-
- Teaching professional software engineering practices improves students’ employment prospects. And
- knowing that Kotlin is a marketable skill, students tend to be more enthusiastic about studying it.
-
-
-
- Kotlin ranked fifth in the category of Most In-Demand Coding Languages Across the Globe from Hired’s 2019 State of Software Engineers Report.
-
-
-
- Kotlin ranked third among programming languages that developers are planning on learning next,
- according
- to HackerRank’s
- 2020 Developer Skills Report.
-
-
-
-
-
-
-
- Kotlin job postings have increased by more than 1400% since 2017
-
-
- Dice
- ↗
-
-
-
-
-
-