(뉴진스 ditto 아님)
App.tsx
(최상단)파일을 DittoProvider로 감싸서 변형을 전달함.npm install @dittowords/cli
👉 간단 설명
: 디자이너가 figma에서 특정 텍스트나 이미지 등 자원 수정 후 ditto 플러그인을 통해 저장
-> ditto-cli pull
or node_modules/.bin/ditto-cli
명령어 실행
-> ditto 폴더 > json 파일들 : 업데이트된 json파일을 확인할 수 있음. (연결 다 해둔 상태라면 코드 수정할 필요 없이 저장, 확인해보면 바로 다 업데이트 된 화면 볼 수 있음.)
// 나는 이미 브랜치에 cli 있고 내부 공유 api key만 입력하면 되어서 npm install --save-dev @dittowords/cli 함.
// 한 브랜치 꼬여서 ~~ --force
$ npx @dittowords/cli
┌──────────────────────────────────┐
│ │
│ Welcome to the Ditto CLI. │
│ │
│ We're glad to have you here. │
│ │
└──────────────────────────────────┘
What is your API key? > key 입력 후 enter
// 내부적으로 Ditto api를 사용하기 때문에 최초 실행 시 key 요청.
✔ What is your API key? · xxx-xxx-xxx
// key 입력 성공 시 확인되는 메세지
Thanks for authenticating.
We'll save the key to: /Users/username/.config/ditto
- 여기까지 하면 key 등록완료.
ditto
라는 폴더 생성됨.ditto init
명령어 실행 -> Ditto 설정 파일(ditto.config.js)이 프로젝트 루트 폴더에 생성됨. ditto
> config.yml
ditto-cli project add
, ditto-cli project remove
ditto-cli pull
: 프로젝트 목록을 읽고 ditto/config.yml
ditto api를 사용해 ditto앱에서 사용할 프로젝트의 데이터를 가져오고 저장함.
- ditto에서 해당 컴포넌트의 데이터를 내려받을 수 있다
- 이처럼 json 파일을 구조도 선택 가능함.
1. Ditto로 이동하여 구성 요소의 ID를 가져온다.
2. 검색 도구를 사용하여 프로젝트에서 텍스트의 모든 인스턴스를 찾는다.
3. JSX 코드의 일부가 아닌 문자열의 인스턴스(예: 함수 이름, 주석 등)를 필터링한다.
4. 텍스트를 <DittoComponent componentId=<id> /> 로 바꿔 적용.
// ----- 🗂️ ditto > config.yml ----
// ditto 샘플
sources:
components:
enabled: true
variants: true
format: flat
// 아래와 같이 프로젝트 아이디 등 각각 설정 가능
sources:
projects:
- id: a1b2c3d4e5f6g7h8i9j10k11l12
name: TRIP YOUNGDVISOR my project (English)
- id: a1b2c3d4e5f6g7h8i9j10k11l122
name: TRIP YOUNGDVISOR my project2 (English)
exclude_components: true
variants: true
format: structured
// source - projects
// : 텍스트를 가져올 프로젝트 목록
// name
// : cli에서 프로젝트를 참조할 때 표시 목적으로 사용되지만, Ditto의 프로젝트 이름과 정확히 일치할 필요는 없음.
// exclude_components
// : 구성 요소와 연결되지 않은 텍스트 항목만 가져와야 함을 나타내기 위해 프로젝트별로 속성을 추가할 수 있음.
// variants
// : 구성된 소스에 대한 텍스트 데이터를 가져올 때 변형 정보를 포함할 수 있음. (false지정하지 않으면 기본값)
// format
// : 지정하지 않으면 기본값. (지정가능 값 = flat, structured, android, ios-strings, ios-stringsdict)
// : 동일한 구성에서 여러 JSON 형식을 지정하면 x -> 디스크에 쓸 때 서로 덮어쓰게 되기 때문.
// 이 외에도 status, root, components 등이 있음. (ditto cli 깃 readme 참조)
// ----- 🗂️ ditto > ex) ditto-component-file-name-example_kr-ko.json ----
{
"my_project_title" : {
"text" : "여행 프로젝트",
"api_id" : "my_project_title-1"
},
"my_project_title-2" : {
"text" : "식단 프로젝트",
"api_id" : "my_project_title-2"
},
"my_project_placeholder" : {
"text" : "추가할 프로젝트명을 입력하세요.",
"api_id" : "my_project_placeholder"
},
.
.
.
}
// 이하 ditto 샘플 json
{
"footer.about.blog": "Blog",
"footer.about.careers": "Careers",
"footer.about.company": "Company",
.
.
.
}
// ----- 🗂️ ditto > index.js -----
// ditto로 적용할 각 key와 source목록
// source목록 = ditto 폴더 하위로 저장된 json데이터들
module.exports = {
"ditto_project_id_example_pye_1" : {
// 아래 json 데이터들은 ditto 폴더 하위로 저장된 json 파일들이다. (코드 아래 사진 참고)
"base" : require('./ditto-component-file-name-example_kr-ko.json'),
"spanish" : require('./ditto-component-file-name-example_spanish.json'),
"us_en" : require('./ditto-component-file-name-example_us-en.json'),
},
"ditto_project_id_example_pye_2" : {
"cn" : require('./ditto-component-file-name-example_cn.json'),
"jp" : require('./ditto-component-file-name-jp.json'),
},
.
.
.
}
// ----- 🗂️ app.tsx -----
import {DittoProvider} from "ditto-react";
import dittoSource from "@ditto/."; // 위의 ditto > index.js
// = import dittoSource from "./ditto";
const projectId = Object.keys(dittoSource);
// const [variant, setVariant] = useState("base")
return (
...
// <DittoProvider source={dittoSource} variant={variant} >
// * projectId = 적용시킬 'ditto 의 해당 json 파일'
// * variant = "us-en"을 적용하면 위의 json 파일 중 us-en으로 설 정한 파일이 적용됨.
// 기본으로 하고싶으면 그냥 variant안쓰면 됨.
<DittoProvider source={dittoSource} projectId={projectId[0]} variant="us-en">
<Component {...pageProps} />
</DittoProvider>
...
)
// ----- 🗂️ component -- ditto 데이터를 사용할 컴포넌트
import {Ditto} from "ditto-react"
const myTitle = "이사"
return(
...
<div>
<input placeholder={`${my_project_placeholder}`} />
<h1><Ditto textId="my_project_title-1" /></h1>
<span><Ditto textId="my_project_text" /></span>
</div>
...
)
👉 ditto에서 제공하는 예시 샘플 소스
{
.
.
"my_project_title-3" : {
"text" : "{{title}} 프로젝트",
// 변수로 처리할 부분을 {{중괄호 두 개}}로 감싸줌. 💥
"api_id" : "my_project_title-3"
},
.
.
}
<h1>
<Ditto textId="my_project_title-1" variables={{title : myTitle}} count={2}/>
// variables에 변수 적용
// count = 복수형 지정 시 사용
</h1>
object
...
// useDittoComponent는 아직 안해봄..
import { Ditto, , useDittoSingleText } from "ditto-react";
//const id = useDittoSingleText({textId : "text-id-1"})
const textName = "text-id-1"
const text = useDittoSingleText({textId : textName });
console.log(text) // "안녕하세요."
console.log(typeof(text)) // string
// 내가 한 것
const [label , setLabel] = useState("");
const textName = "text-id-"
const text = useDittoSingleText({textId : textName + label })
onClick={()=>setLabel(
value === "호두"
? "1"
: value === "자두"
? "2"
: "3"
);}
...
🏷️ componentId
<h2><Ditto componentId="footer.about.blog" /></h2>
// - Ditto를 사용하여 특정 컴포넌트 또는 섹션에 연결된 고유한 식별자를 나타내는 속성.
// (컴포넌트 레벨에서 다국어 번역 또는 다른 변수를 관리)
// - 이를 통해 Ditto는 해당 컴포넌트와 관련된 다국어 번역 또는 다른 변수 데이터를 제공.
🏷️ textId
<h2><Ditto textId="my_project_text" /></h2>
// - 특정 텍스트 또는 문자열의 식별자를 나타내는 속성.
// - 특정 텍스트 또는 문자열과 관련된 데이터를 제공.
🏷️ locale
<Ditto componentId="example" locale="fr-FR" />
// - Ditto에서 사용할 로컬(언어 및 지역 설정)을 정의.
// - 이를 통해 다국어 지원을 위해 다른 언어로 텍스트를 렌더링하거나 다른 지역 설정에 맞게 형식을 지정할 수 있음.
🏷️ variant
<Ditto componentId="button" variant="primary" />
<Ditto textId="call-to-action" variant="urgent" />
// - 특정 컴포넌트 또는 텍스트에 대한 여러가지 변수 관리.
// - 사용 예) 버튼 컴포넌트의 다양한 스타일을 나타내거나 텍스트의 강조 효과를 변경 등.
🏷️ format
<Ditto textId="date" format="longDate" />
<Ditto textId="price" format="currency" />
// - 텍스트 또는 숫자와 같은 값을 형식화하기 위해 사용.
// - 날짜, 시간 또는 숫자와 관련된 형식을 제어하며, 로케일에 따라 다른 형식을 적용할 수 있음.
🏷️ data
<Ditto componentId="product-description" data={productData} />
<Ditto textId="user-greeting" data={userData} />
// - 컴포넌트 또는 텍스트와 관련된 추가 데이터를 전달하는 데 사용.
// - 사용 예) 동적 데이터를 가져와서 텍스트와 함께 렌더링, 다른 사용자 지정 데이터를 전달 등.
🏷️ fallback
<Ditto componentId="example" fallback="Default Text" />
<Ditto textId="greeting" fallback="Hello, Guest" />
// - 주어진 컴포넌트 또는 텍스트의 다국어 지원이 없는 경우에 대비한 기본 텍스트 또는 값.
// - 로컬에 대응하는 번역이 없을 때 사용함.
🏷️ placeholders
<Ditto componentId="loading" placeholders={{ text: 'Loading...', component: <Spinner /> }} />
// - 비동기 데이터를 로드할 때 표시할 placeholder 문구 또는 구성 요소를 정의하는 데 사용.
출력 예시 :
안녕하세요
저는 자두입니다.
ditto :
"textDitto" :{
"text": "안녕하세요\n 저는 자두입니다.",
}
code :
<span className="whitespace-pre">
<Ditto textId="textDitto" /> // x 이렇게하면 \n무시되고 한 줄로 나옵니다.
<Ditto textId="textDitto" richText/> // o
</span>
// ditto json
...
"ditto-Body-Id":{
"text" : "{{text}}의 <span style='color:red;'>{{name}}</span>입니다.",
"api-id" : "ditto-Body-Id",
"variants" : {
"KR-ko" : {
"text" : "{{text}}의 <span style='color:red;'>{{name}}</span>입니다."
}
.
.
.
}
}
// DittoTest.tsx
import parse from "html-react-parser";
const DittoTest = () => {
const city = "서울"
const age = "2"
//const dittoAge = useDittoSingleText({
// "{{age}}살 입니다."
//textId : "ditto-text-id",
//variables : {
// text : `${age}${"살입니다."}`
//}
//})
const dittoBodyId = useDittoSingleText({
// "{{text}}의 {{name}}입니다."
textId : "ditto-Body-Id",
variables : {
text: `${city}`,
name: `${"호두자두뚜뚜"}
}
});
return (
<div>
<span>
<Ditto textId="ditto-header-id" />
</span>
<span>
{ parse( dittoBodyId ) }
</span>
<span>
<Ditto textId="ditto-text-id" variables={{ age : age }} />
</span>
</div>
)
}
export default DittoTest;
🟢 Ditto 사용 후기
// ex) 홈, 마이페이지, 설정 화면에 '닫기'버튼이 모두 있는 경우
// base.json
"home-close":{
"text" : "닫기",
"api-id" : "home-close",
"variants" : {
"kr-ko" : {"text" : "닫기"},
"us-en" : {"text" : "Close"},
}
},
"myPage-close":{
"text" : "닫기",
"api-id" : "myPage-close",
"variants" : {
"kr-ko" : {"text" : "닫기"},
"us-en" : {"text" : "Close"},
}
},
"settings-close":{
"text" : "닫기",
"api-id" : "settings-close",
"variants" : {
"kr-ko" : {"text" : "닫기"},
"us-en" : {"text" : "Close"},
}
},
// 바뀌지 않을 ditto 중복이 너무 많다.
// (내 생각 - 명확한 것은 요소를 공통 사용하고 혹시 앞뒤로 내용이 달라진다면 앞뒤의 새로운 요소만 추가하면 되지 않을까?)
"close":{
"text" : "닫기",
"api-id" : "close",
"variants" : {
"kr-ko" : {"text" : "닫기"},
"us-en" : {"text" : "Close"},
}
},